조아마시

쓸모 있는 상세페이지 만들기

웹개발/javascript

[자바스크립트] Yup 사용하기

joamashi 2024. 7. 30. 00:33

Yup은 자바스크립트에서 데이터 유효성 검사를 간편하고 효율적으로 수행할 수 있도록 도와주는 라이브러리입니다. 특히, 폼 데이터의 유효성을 검증하는 데 많이 사용됩니다.

왜 Yup을 사용해야 할까요?

  • 간결한 코드: 복잡한 유효성 검사 로직을 직접 작성하는 대신, Yup의 제공하는 다양한 검사 규칙을 조합하여 간결하게 표현할 수 있습니다.
  • 재사용 가능한 스키마: 한 번 정의한 스키마를 여러 곳에서 재사용할 수 있어 코드 중복을 줄이고 유지보수를 용이하게 합니다.
  • 타입스크립트와의 호환성: 타입스크립트와의 통합이 잘 되어 있어 강력한 타입 안전성을 제공합니다.
  • 다양한 검사 규칙: 문자열 길이 제한, 숫자 범위, 필수 입력 여부 등 다양한 유형의 검사 규칙을 제공합니다.
  • 커스텀 검사 규칙: 기본 제공되는 규칙 외에도 사용자 정의 검사 함수를 만들어 추가할 수 있습니다.

어떻게 사용하나요?

import * as yup from 'yup';

const userSchema = yup.object().shape({
  name: yup.string().required('이름은 필수입니다.'),
  email: yup.string().email('올바른 이메일 형식이 아닙니다.').required('이메일은 필수입니다.'),
  age: yup.number().positive().integer().required('나이는 양의 정수여야 합니다.'),
});

위 예시는 사용자 정보를 검증하는 스키마를 정의한 것입니다. yup.object().shape() 메서드를 사용하여 객체 형태의 스키마를 만들고, 각 속성에 대한 검사 규칙을 지정합니다.

  • required(): 필수 입력 여부를 검사합니다.
  • email(): 이메일 형식인지 검사합니다.
  • positive(): 양수인지 검사합니다.
  • integer(): 정수인지 검사합니다.

Yup의 주요 기능

  • 스키마 정의: 데이터의 구조와 유효성 검사 규칙을 정의합니다.
  • 유효성 검사: 정의된 스키마에 따라 데이터의 유효성을 검사하고, 문제가 발생하면 에러 메시지를 반환합니다.
  • 형 변환: 검증된 데이터를 원하는 형태로 변환합니다.
  • 커스텀 검사 함수: 사용자 정의 검사 로직을 추가할 수 있습니다.

언제 사용하면 좋을까요?

  • 폼 데이터 유효성 검사: 사용자가 입력한 데이터가 올바른 형식인지 검사해야 할 때
  • API 요청 데이터 유효성 검사: 서버로 전송하기 전에 데이터의 유효성을 검사해야 할 때
  • 데이터 모델 정의: 데이터의 구조를 명확하게 정의하고 유효성을 보장해야 할 때

Vue.js에서 Yup 설치하기

Yup 설치

터미널에서 다음 명령 중 하나를 실행하여 Yup을 설치합니다.

npm 사용 시:

npm install yup

 

String 스키마 다양한 예시

Yup에서 문자열(string) 스키마를 활용하여 다양한 유효성 검사를 수행할 수 있습니다. 아래는 자주 사용되는 예시들입니다.

기본적인 문자열 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  name: yup.string().required('이름은 필수입니다.')
});
  • required: 필수 입력 여부 검사

문자열 길이 제한

import * as yup from 'yup';

const schema = yup.object().shape({
  password: yup.string().min(8, '비밀번호는 8자리 이상이어야 합니다.').max(20, '비밀번호는 20자리를 초과할 수 없습니다.')
});
  • min: 최소 길이 검사
  • max: 최대 길이 검사

정규 표현식을 이용한 패턴 매칭

import * as yup from 'yup';

const schema = yup.object().shape({
  email: yup.string().email('올바른 이메일 형식이 아닙니다.').required('이메일은 필수입니다.'),
  phoneNumber: yup.string().matches(/^\d{3}-\d{3}-\d{4}$/, '전화번호 형식이 올바르지 않습니다.')
});
  • email: 이메일 형식 검사
  • matches: 정규 표현식을 이용한 패턴 매칭

특정 값 포함 여부 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  role: yup.string().oneOf(['admin', 'user'], '역할은 admin 또는 user여야 합니다.')
});
  • oneOf: 지정된 값 중 하나인지 검사

커스텀 검사 함수 활용

import * as yup from 'yup';

const isStrongPassword = (password) => {
  // 복잡한 비밀번호 검사 로직 구현
  return password.length >= 10 && /[a-z]/.test(password) && /[A-Z]/.test(password) && /\d/.test(password);
};

const schema = yup.object().shape({
  password: yup.string().test('isStrongPassword', '비밀번호가 너무 약합니다.', isStrongPassword)
});
  • test: 커스텀 검사 함수를 이용한 검사

추가적인 예시

  • trim: 문자열 앞뒤 공백 제거: yup.string().trim()
  • lowercase: 문자열을 소문자로 변환: yup.string().lowercase()
  • uppercase: 문자열을 대문자로 변환: yup.string().uppercase()

실제 사용 예시 (Vue.js 컴포넌트)

<template>
  <form @submit.prevent="handleSubmit">
    <input type="text" v-model="formData.name" />
    <button type="submit">Submit</button>
  </form>
</template>

<script>
import * as yup from 'yup';

export default {
  data() {
    return {
      formData: {
        name: ''
      }
    }
  },
  methods: {
    handleSubmit() {
      const schema = yup.object().shape({
        name: yup.string().required('이름은 필수입니다.')
      });

      schema.validate(this.formData)
        .then(() => {
          // 유효성 검사 통과 시 처리
        })
        .catch(err => {
          // 유효성 검사 실패 시 처리
        });
    }
  }
}
</script>

Number 스키마 다양한 예시

Yup에서 숫자(number) 스키마를 활용하여 다양한 유효성 검사를 수행할 수 있습니다. 아래는 자주 사용되는 예시들입니다.

기본적인 숫자 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  age: yup.number().required('나이는 필수입니다.')
});
  • required: 필수 입력 여부 검사

숫자 범위 제한

import * as yup from 'yup';

const schema = yup.object().shape({
  score: yup.number().min(0).max(100, '점수는 0에서 100 사이여야 합니다.')
});
  • min: 최솟값 검사
  • max: 최댓값 검사

정수만 허용

import * as yup from 'yup';

const schema = yup.object().shape({
  quantity: yup.number().integer().positive('수량은 양의 정수여야 합니다.')
});
  • integer: 정수만 허용
  • positive: 양수만 허용

소수점 자릿수 제한

import * as yup from 'yup';

const schema = yup.object().shape({
  price: yup.number().positive().precision(2, '가격은 소수점 둘째 자리까지 허용됩니다.')
});
  • precision: 소수점 자릿수 제한

커스텀 검사 함수 활용

import * as yup from 'yup';

const isEvenNumber = (value) => {
  return value % 2 === 0;
};

const schema = yup.object().shape({
  number: yup.number().test('isEven', '짝수만 입력 가능합니다.', isEvenNumber)
});
  • test: 커스텀 검사 함수를 이용한 검사

실제 사용 예시 (Vue.js 컴포넌트)

<template>
  <form @submit.prevent="handleSubmit">
    <input type="number" v-model.number="formData.age" />
    <button type="submit">Submit</button>
  </form>
</template>

<script>
import * as yup from 'yup';

export default {
  data() {
    return {
      formData: {
        age: 0
      }
    }
  },
  methods: {
    handleSubmit() {
      const schema = yup.object().shape({
        age: yup.number().min(18, '만 18세 이상이어야 합니다.')
      });

      schema.validate(this.formData)
        .then(() => {
          // 유효성 검사 통과 시 처리
        })
        .catch(err => {
          // 유효성 검사 실패 시 처리
        });
    }
  }
}
</script>

Boolean 스키마 다양한 예시

Yup에서 Boolean 스키마를 활용하여 참/거짓 값에 대한 유효성 검사를 수행할 수 있습니다.

기본적인 Boolean 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  isAgreed: yup.boolean().required('동의 여부는 필수입니다.')
});
  • required: 필수 입력 여부 검사

조건부 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  isAdult: yup.boolean(),
  birthYear: yup.number().when('isAdult', {
    is: true,
    then: yup.number().min(1900).max(new Date().getFullYear() - 18),
    otherwise: yup.number().min(1900)
  })
});
  • when: isAdult 값에 따라 birthYear에 대한 검사 규칙을 다르게 적용

배열 요소의 Boolean 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  permissions: yup.array().of(yup.boolean())
});
  • array().of: 배열 요소가 모두 boolean 타입인지 검사

커스텀 검사 함수 활용

import * as yup from 'yup';

const schema = yup.object().shape({
  isActive: yup.boolean().test('isActive', '활성화 상태여야 합니다.', (value) => value === true)
});
  • test: 커스텀 검사 함수를 이용하여 특정 조건을 검사

실제 사용 예시 (Vue.js 컴포넌트)

<template>
  <form @submit.prevent="handleSubmit">
    <input type="checkbox" v-model="formData.isAgreed" /> 동의합니다.
    <button type="submit">Submit</button>
  </form>
</template>

<script>
import * as yup from 'yup';

export default {
  data() {
    return {
      formData: {
        isAgreed: false
      }
    }
  },
  methods: {
    handleSubmit() {
      const schema = yup.object().shape({
        isAgreed: yup.boolean().required('동의해주세요.')
      });

      schema.validate(this.formData)
        .then(() => {
          // 유효성 검사 통과 시 처리
        })
        .catch(err => {
          // 유효성 검사 실패 시 처리
        });
    }
  }
}
</script>

Date 스키마 다양한 예시

Yup에서 Date 스키마를 활용하여 날짜 유효성 검사를 수행할 수 있습니다. 다양한 상황에 맞춰 날짜 형식, 범위, 비교 등을 검증할 수 있습니다.

기본적인 날짜 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  birthDate: yup.date().required('생년월일은 필수입니다.')
});
  • required: 필수 입력 여부 검사

날짜 범위 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  startDate: yup.date().min(new Date(), '시작 날짜는 오늘 이후여야 합니다.'),
  endDate: yup.date().max(new Date(), '종료 날짜는 오늘 이전일 수 없습니다.')
});
  • min: 최소 날짜 검사
  • max: 최대 날짜 검사

특정 날짜와 비교

import * as yup from 'yup';

const schema = yup.object().shape({
  expireDate: yup.date().min(new Date('2024-12-31'), '유효 기간이 만료되었습니다.')
});

날짜 형식 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  createdAt: yup.date().default(function() { return new Date(); })
});
  • default: 기본값 설정 (현재 날짜)

커스텀 검사 함수 활용

import * as yup from 'yup';

const isWeekend = (value) => {
  const day = value.getDay();
  return day === 0 || day === 6; // 일요일 또는 토요일인 경우
};

const schema = yup.object().shape({
  eventDate: yup.date().test('isWeekend', '주말에는 이벤트를 진행할 수 없습니다.', isWeekend)
});
  • test: 커스텀 검사 함수를 이용한 검사

실제 사용 예시 (Vue.js 컴포넌트)

<template>
  <form @submit.prevent="handleSubmit">
    <input type="date" v-model="formData.birthDate" />
    <button type="submit">Submit</button>
  </form>
</template>

<script>
import * as yup from 'yup';

export default {
  data() {
    return {
      formData: {
        birthDate: null
      }
    }
  },
  methods: {
    handleSubmit() {
      const schema = yup.object().shape({
        birthDate: yup.date().required('생년월일은 필수입니다.')
      });

      schema.validate(this.formData)
        .then(() => {
          // 유효성 검사 통과 시 처리
        })
        .catch(err => {
          // 유효성 검사 실패 시 처리
        });
    }
  }
}
</script>

Array 스키마 다양한 예시

Yup에서 Array 스키마를 활용하여 배열 형태의 데이터에 대한 유효성 검사를 수행할 수 있습니다. 배열 요소의 타입, 개수, 중복 허용 여부 등을 다양하게 설정하여 정교한 검사를 진행할 수 있습니다.

기본적인 배열 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  numbers: yup.array().required('숫자 배열은 필수입니다.')
});
  • required: 배열이 필수 입력인 경우

배열 요소의 타입 지정

import * as yup from 'yup';

const schema = yup.object().shape({
  colors: yup.array().of(yup.string())
});
  • of: 배열 요소가 모두 문자열 타입인 경우

배열 요소의 개수 제한

import * as yup from 'yup';

const schema = yup.object().shape({
  tags: yup.array().of(yup.string()).min(2).max(5)
});
  • min: 최소 개수 제한
  • max: 최대 개수 제한

배열 요소의 유일성 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  uniqueNumbers: yup.array().of(yup.number()).unique()
});
  • unique: 중복된 값을 허용하지 않음

배열 요소의 커스텀 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  positiveNumbers: yup.array().of(yup.number().positive())
});
  • positive: 배열 요소가 모두 양수인 경우

복잡한 객체 배열

import * as yup from 'yup';

const userSchema = yup.object().shape({
  name: yup.string(),
  age: yup.number()
});

const schema = yup.object().shape({
  users: yup.array().of(userSchema)
});
  • of: 배열 요소가 userSchema와 일치하는 객체인 경우

실제 사용 예시 (Vue.js 컴포넌트)

<template>
  <form @submit.prevent="handleSubmit">
    <input type="text" v-model="formData.tags" />
    <button type="submit">Submit</button>
  </form>
</template>

<script>
import * as yup from 'yup';

export default {
  data() {
    return {
      formData: {
        tags: []
      }
    }
  },
  methods: {
    handleSubmit() {
      const schema = yup.object().shape({
        tags: yup.array().of(yup.string()).min(2).max(5)
      });

      schema.validate(this.formData)
        .then(() => {
          // 유효성 검사 통과 시 처리
        })
        .catch(err => {
          // 유효성 검사 실패 시 처리
        });
    }
  }
}
</script>

Object 스키마 다양한 예시

Yup에서 Object 스키마를 활용하면 복잡한 객체 형태의 데이터에 대한 유효성 검사를 수행할 수 있습니다. 각 객체의 프로퍼티에 대한 다양한 검사 규칙을 설정하여 데이터의 일관성을 유지할 수 있습니다.

기본적인 객체 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  name: yup.string().required(),
  age: yup.number().positive().integer()
});
  • shape: 객체의 구조를 정의합니다.
  • required: 필수 입력 여부를 검사합니다.
  • positive: 양수만 허용합니다.
  • integer: 정수만 허용합니다.

중첩된 객체 검사

import * as yup from 'yup';

const addressSchema = yup.object().shape({
  street: yup.string().required(),
  city: yup.string().required(),
  zipcode: yup.string().matches(/^\d{5}$/)
});

const userSchema = yup.object().shape({
  name: yup.string().required(),
  age: yup.number().positive().integer(),
  address: addressSchema
});
  • 중첩된 shape: 객체 내부에 또 다른 객체를 정의하여 복잡한 구조를 표현합니다.

조건부 검사

import * as yup from 'yup';

const schema = yup.object().shape({
  isAdult: yup.boolean(),
  birthYear: yup.number().when('isAdult', {
    is: true,
    then: yup.number().min(1900).max(new Date().getFullYear() - 18),
    otherwise: yup.number().min(1900)
  })
});
  • when: 특정 조건에 따라 다른 검사 규칙을 적용합니다.

배열 내 객체 검사

import * as yup from 'yup';

const userSchema = yup.object().shape({
  name: yup.string(),
  age: yup.number()
});

const schema = yup.object().shape({
  users: yup.array().of(userSchema)
});
  • array().of: 배열 요소가 특정 스키마와 일치하는 객체인지 검사합니다.

커스텀 검사 함수 활용

import * as yup from 'yup';

const isStrongPassword = (password) => {
  // 복잡한 비밀번호 검사 로직 구현
  return password.length >= 10 && /[a-z]/.test(password) && /[A-Z]/.test(password) && /\d/.test(password);
};

const schema = yup.object().shape({
  password: yup.string().test('isStrongPassword', '비밀번호가 너무 약합니다.', isStrongPassword)
});
  • test: 커스텀 검사 함수를 이용하여 특정 조건을 검사합니다.

실제 사용 예시 (Vue.js 컴포넌트)

<template>
  <form @submit.prevent="handleSubmit">
    <input type="text" v-model="formData.name" />
    <input type="number" v-model.number="formData.age" />
    <button type="submit">Submit</button>
  </form>
</template>

<script>
import * as yup from 'yup';

export default {
  data() {
    return {
      formData: {
        name: '',
        age: 0
      }
    }
  },
  methods: {
    handleSubmit() {
      const schema = yup.object().shape({
        name: yup.string().required('이름은 필수입니다.'),
        age: yup.number().positive().integer().required('나이는 양의 정수여야 합니다.')
      });

      schema.validate(this.formData)
        .then(() => {
          // 유효성 검사 통과 시 처리
        })
        .catch(err => {
          // 유효성 검사 실패 시 처리
        });
    }
  }
}
</script>

다양한 규칙 정의 예시

기본 데이터 형식 검사

import * as yup from 'yup';

const schema = yup.object({
  name: yup.string().required('이름은 필수입니다.'),
  age: yup.number().positive('나이는 양수여야 합니다.').integer('나이는 정수여야 합니다.'),
  email: yup.string().email('올바른 이메일 형식이 아닙니다.'),
});
  • string(): 문자열 검사
  • number(): 숫자 검사
  • boolean(): 불리언 검사
  • date(): 날짜 검사

길이 제한

const schema = yup.object({
  password: yup.string().min(8, '비밀번호는 8자리 이상이어야 합니다.').max(20, '비밀번호는 20자리를 초과할 수 없습니다.'),
});

패턴 검사

const schema = yup.object({
  phoneNumber: yup.string().matches(/^\d{3}-\d{3}-\d{4}$/, '전화번호 형식이 올바르지 않습니다.'),
});

조건부 검사

const schema = yup.object({
  isAdult: yup.boolean(),
  age: yup.number().when('isAdult', {
    is: true,
    then: yup.number().min(19, '성인이라면 나이는 19세 이상이어야 합니다.'),
  }),
});

배열 검사

const schema = yup.object({
  hobbies: yup.array().of(yup.string()).min(2, '취미는 2개 이상 선택해야 합니다.'),
});

커스텀 검사 함수

const schema = yup.object({
  customField: yup.string().test('is-custom', '커스텀 조건을 만족하지 않습니다.', (value) => {
    // 커스텀 검사 로직
    return value.length > 5;
  }),
});

Yup를 활용한 유효성 검사 예시

const data = {
  name: 'John Doe',
  age: 25,
  email: 'johndoe@example.com',
};

schema.validate(data)
  .then(validData => {
    console.log('유효한 데이터:', validData);
  })
  .catch(err => {
    console.error('유효성 검사 오류:', err.errors);
  });
728x90