16. Vue JS/Vue 2

20. Vue2 - 유효성 검사 모듈 Vee Validation ^3.4.11

THE HEYDAZE 2021. 11. 16. 00:43
  OS   Windows 10 PRO 64bit 버전 20H2 (OS 빌드 19042.867)
  Vue   2.5.13
  Vee Validation   ^3.4.11

 

공식 홈

https://vee-validate.logaretm.com/v4/v4/guide/global-validators#defining-global-validators

 

모듈 설치
npm install vee-validate@3.4.11

프로젝트명과 같은 경우 설치 오류가 발생할 수 있습니다

 

Vue 전역 컴포넌트로 등록 + extend 활용
vee-validation.js
import Vue from 'vue';
import { extend, ValidationObserver, ValidationProvider } from 'vee-validate';
import {
  required,
  digits,
  numeric,
  email,
  confirmed,
} from 'vee-validate/dist/rules';

extend('limit', (value, params) => {
  const [min, max] = params;
  if ((value && value.length < min) || value.length > max) {
    return `{_field_} 필드는 ${min}자 ~ ${max}자를 초과할 수 없습니다`;
  }
  return true;
});

extend('required', {
  ...required,
  message: '{_field_} 필드는 반드시 입력해야 합니다',
});

extend('required-select', {
  ...required,
  message: '{_field_} 필드는 반드시 선택해야 합니다',
});

extend('numeric', {
  ...numeric,
  message: '{_field_} 필드는 숫자로만 구성되어야 합니다',
});
extend('digits', {
  ...digits,
  message: '{_field_} 필드는 11자리 여야 합니다',
});

extend('email', {
  ...email,
  message: '잘못 입력된 이메일 주소 입니다',
});

// provider 에 :rules="{ confirmed: 'provider name 명을 적어주면 된다'}"
extend('confirmed', {
  ...confirmed,
  message: '비밀번호와 비밀번호확인이 일치하지 않습니다',
});

Vue.component('ValidationObserver', ValidationObserver);
Vue.component('ValidationProvider', ValidationProvider);

 

작성된 모듈 사용하기
main.js
import Vue from 'vue';
import App from './App.vue';
import '@/plugin/vee-validation';

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App),
}).$mount('#app');

 

페이지

이메일 validation

SignUpPage.vue
<template>
  <div>
    <h1>싱글 페이지</h1>

    <form >
      <validation-provider
        rules="email"
        name="이메일"
        v-slot="{errors}"
      >
        <div>
          <label>이메일</label>
          <input v-model="formData.email" type="text" name="이메일" value="">
        </div>
        <div>
          {{errors}}
        </div>
      </validation-provider>

    </form>
  </div>
</template>

<script>
export default {
  name: 'SignUpPage',
  data() {
    return {
      formData: {
        email: '',
      },
    };
  },

};
</script>

<style scoped>
div {
  margin-bottom: 8px;
}

</style>

- rules 는 이 필드에서 유효성을 검사할 항목들을 지정한다
  vee-validation.js 에서 extend 로 정의했던 유효성을 사용할 수 있으며, 또는 직접 method 로 유효성검사를 할 수 있다

- name 은 에러가 발생했을 때 `_field` 명의 기본 명칭을 정의해주기 위해 사용된다 - 예시) OO필드는 필수 입니다

- v-slot 은 해당 컴포넌트의 slot 부분을 가져오기 위해 사용하였다

 

버튼을 통한 invalid 체크

버튼을 통한 validation

<template>
  <div>
    <h1>싱글 페이지</h1>

    <form @submit.prevent="submit">
      <validation-provider
        ref="emailProvider"
        rules="required|email"
        name="이메일"
        v-slot="{errors}"
      >
        <div>
          <label>이메일</label>
          <input v-model="formData.email" type="text" name="이메일" value="">
        </div>
        <div>
          {{errors}}
        </div>
      </validation-provider>

      <button>버튼</button>

    </form>
  </div>
</template>

<script>
export default {
  name: 'SignUpPage',
  data() {
    return {
      formData: {
        email: '',
      },
    };
  },

  methods: {
    submit() {
      const { emailProvider } = this.$refs;
      console.log(emailProvider);

      emailProvider.validate().then((result) => {
        console.log(result);
        if (result.valid) console.log('post api');
        else console.error('form invalid');
      });
    },
  },
};
</script>

<style scoped>
div {
  margin-bottom: 8px;
}

</style>

&amp;lt;validation-prodiver&amp;gt; 속성 - 1
&amp;lt;validation-prodiver&amp;gt; 속성 - 2

<validation-prodiver> 를 통하여 해당 필드명, 입력했던 값, 현재 에러내용, flag 내용을 알 수 있으며, validation() 함수를 호출하여 새롭게 유효성 검사 체크를 할 수 있다

 

v-slot 의 내용들은 validation() 함수를 통해 얻어는 결과가 담겨져있으며, v-slot="{errors}" 를 사용하여 에러 배열 부분만 가져와 사용하였다

 

v-data 를 통한 rules 방식

<template>
  <div>
    <h1>싱글 페이지</h1>

    <form @submit.prevent="submit">
      <validation-provider
        ref="emailProvider"
        :rules="validateCheck"
        name="이메일"
        v-slot="{errors}"
      >
        <div>
          <label>이메일</label>
          <input v-model="formData.email" type="text" name="이메일" value="">
        </div>
        <div>
          {{errors}}
        </div>
      </validation-provider>

      <button>버튼</button>

    </form>
  </div>
</template>

<script>
export default {
  name: 'SignUpPage',
  data() {
    return {
      formData: {
        email: '',
      },
      validateCheck: {
        required: true,
        email: true,
        limit: [1, 11],
      },
    };
  },

  methods: {
    submit() {
      const { emailProvider } = this.$refs;
      console.log(emailProvider);

      emailProvider.validate().then((result) => {
        console.log(result);
        if (result.valid) console.log('post api');
        else console.error('form invalid');
      });
    },
  },
};
</script>

<style scoped>
div {
  margin-bottom: 8px;
}

</style>

- required 는 필수 입력

- email 은 이메일 형식

- limit 은 min 과 max 를 의미한다

 

- 다른 방식으로 아래와 같이 할 수 있다

<validation-provider
        ref="emailProvider"
        :rules="{
        required: true,
        email: true,
        limit: [1, 14],
        }"
        name="이메일"
        v-slot="{errors}"
>
        <div>
          <label>이메일</label>
          <input v-model="formData.email" type="text" name="이메일" value="" autocomplete="off">
        </div>
        <div>
          {{errors}}
        </div>
</validation-provider>

 

<validation-provider
        ref="emailProvider"
        rules="required|email|limit:1,14"
        name="이메일"
        v-slot="{errors}"
      >
        <div>
          <label>이메일</label>
          <input v-model="formData.email" type="text" name="이메일" value="" autocomplete="off">
        </div>
        <div>
          {{errors}}
        </div>
</validation-provider>

 

여러 컴포넌트 적용해보기

전체 유효성 검사

<template>
  <div>
    <h1>싱글 페이지</h1>
    <validation-observer ref="validator">
      <form @submit.prevent="submit">
        <validation-provider
          rules="required|email|limit:1,14"
          name="이메일"
          v-slot="{errors}"
        >
          <div>
            <label>이메일</label>
            <input v-model="formData.email" type="text" name="이메일" value=""
                   autocomplete="off">
          </div>
          <div>
            {{ errors }}
          </div>
        </validation-provider>

        <validation-provider rules="required" name="패스워드" v-slot="{errors}">
          <div>
            <label>비밀번호</label>
            <input v-model="formData.password" type="text" name="" value="">
          </div>
          <div>
            {{ errors }}
          </div>
        </validation-provider>

        <validation-provider rules="required|confirmed:패스워드" name="패스워드확인"
                             v-slot="{errors}">
          <div>
            <label>비밀번호 확인</label>
            <input v-model="formData.passwordCheck" type="text" name=""
                   value="">
          </div>
          <div>
            {{ errors }}
          </div>
        </validation-provider>

        <validation-provider rules="required" name="휴대폰" v-slot="{errors}">
          <div>
            <label>휴대폰</label>
            <input v-model="formData.tell" type="text" name="" value="">
          </div>
          <div>
            {{ errors }}
          </div>
        </validation-provider>

        <!-- v-model 에서 '' 또는 null 로 기본값으로 세팅해주어야 함, false 로 할 경우 required 먹히지 않음 -->
        <validation-provider rules="required" name="성별" v-slot="{errors}">
          <div>
            <label>성별</label>

            <input v-model="formData.gender" type="radio" name="gender"
                   value="1">
            <label>남</label>
            <input v-model="formData.gender" type="radio" name="gender"
                   value="2">
            <label>여</label>
          </div>
          <div>
            {{ errors }}
          </div>
        </validation-provider>

        <validation-provider rules="required-select" name="취미" v-slot="{errors}">
          <div>
            <label>취미</label>
            <input v-model="formData.hobby" type="checkbox" name="hobby"
                   value="A">
            <label>A</label>
            <input v-model="formData.hobby" type="checkbox" name="hobby"
                   value="B">
            <label>B</label>
            <input v-model="formData.hobby" type="checkbox" name="hobby"
                   value="C">
            <label>C</label>
          </div>
          <div>
            {{ errors }}
          </div>
        </validation-provider>

        <button>버튼</button>
      </form>
    </validation-observer>

  </div>
</template>

<script>
export default {
  name: 'SignUpPage',
  data() {
    return {
      formData: {
        email: '',
        password: '',
        passwordCheck: '',
        tell: '',
        gender: '',
        hobby: [],
      },
    };
  },

  methods: {
    submit() {
      const { validator } = this.$refs;
      console.log(validator);

      validator.validate().then((result) => {
        console.log(result);
        if (result.valid) console.log('post api');
        else console.error('form invalid');
      });
    },
  },
};
</script>

<style scoped>
div {
  margin-bottom: 8px;
}

</style>

'16. Vue JS > Vue 2' 카테고리의 다른 글

19. Vue2 - Vuex 데이터 관리방법  (0) 2021.10.01
17. Vue2 - @Input  (0) 2021.07.25
16. Vue 2 - Vuex Module 분리하기  (0) 2021.04.20
15. Vue 2 - Axios interceptor Loading Spinner  (0) 2021.04.02
14. Vue 2 - Vue Storybook  (0) 2021.03.31