Vuetify 방식의 실시간 검증 방식
최근 인턴 프로젝트에서 Vue를 사용하게되었는데, UI프레임워크를 사용해서 Validation처리를 손쉽게 하고 싶었고, UI 프레임워크중 material 스타일에 가장 맞는 스타일중 하나인 Vuetify를 선택해서 개발을 시작하게 되었다.
Vuetify의 Form-validation
vuetify는 기본적으로 form input에서 validation을 제공한다. :rule 을 활용하면 validate를 적용할 수있다.
실시간 검증을 하기위해서는 비동기적으로 구현해야한다. 개인적으로 ES6를 활용하고 싶었으나, 아쉽게 실패했고 그 대안으로 axios를 활용해서 구현했었다.
아래는 vuetify의 form 안의 input 값들을 validation 하는 기능을 기본적으로 제공한다. 그중 v-text-field
의 rule을 활용한 것인데, 다음처럼 넣으면 validate처리가 쉽게 된다.
<v-text-field v-model="fields.email" label="이메일 주소" :error-messages="email_dup" :rules="[rules.email.required, rules.email.valid, rules.email.duplicate]" ></v-text-field>
Vue파일 내부에 data에 rules를 지정해놓으면 된다. 아래 메소드를 다음과 같이 적용하면된다.
data(){
return {
email_dup: [],
fields: {
...
email: '',
...
},
rules: {
...
email: {
required: v => !!v || 'E-mail is required',
duplicate: v => this.duplicateEmail(v)
}
....
},
methods:{
...
duplicateEmail(v) {
axios.post('/email-validate', this.fields).then(response => {
this.email_dup = []
}).catch(error => {
this.email_dup = ['이미 탈퇴하거나 이미 가입한 회원입니다.']
})
}
}
rules라는 object 타입을 굳이 만들지 않아도 되긴하지만 일정 형식을 구성해서 만드는게 더 구체적으로 명시하는것 같아서 만들어 놓은것이다.
이 Rules 타입은 return 타입이 boolean 이거나, string 타입인 경우에만 validation이 정상적으로 작동하는데, required: v => !!v || 'E-mail is required',
와 같은 코드를 확인해보면 v안의 값이 있는지 확인하고 false라면 string안의 문구를 input에 띄워주는 방식으로 작동해보였다.
하지만, 여기서 가장 큰 문제는 한가지가 존재하는데, 비동기적으로 이 방식을 처리하는 법이 쉽지 않다는 점이다.
<v-text-field :rules
자체에서 제공하는 기능 function으로 true 혹은 string을 리턴하면 유효성처리를 알아서 해주는데, axios return을 하다보니까 아무래도 Promise과 같이 좀 오류점이 있는듯했다.
https://stackoverflow.com/questions/49132167/how-to-validate-vuetify-text-field-asynchronously
이 링크를 보면 확인해보면, 결국 return되는 값이 Promise로 전달되서 오류가 발생해보이는 듯 했다. console.log로 찍어봤는데 undefined
가 나오는 것을 보아 결정적으로 확신했다.
그렇다면 바로 적용시킬수는 없고 어떤 방식으로 처리할 수 있을까?
나는 이것을 :rule에 맞는 방식은 아니지만, 다른 방식으로 valid 문구를 띄울 수 있었는데, 그 방법은 다음과 같다.
data에 email_dup를 state로 설정한다. 그리고 rules에서 valid를 적용. 그리고 이 duplicateEmail에서는 상태를 변경하고 이 상태가 변경되면, :error_message에서 노출시키는 방법을 활용했다.
이 방법은 SPA 방식으로 만드는 사람들에게는 유효하지 않을까라는 생각을 한다.
추가적으로
await와 async를 통해서 좀 더 깔끔하게 처리할 수 있을거라고 생각했는데, 결국 async의 경우는 결국에는 promise 타입형태로 return 되기 때문에, :rules 타입은 string, boolean 타입이외에는 받을수가 없어서 오류처리가 되어 fail... 비동기적인 방식을 살리면서 vuetify의 기본 validation 기능을 활용하는것은 사실상 주어진 방식으로 할 수는 없다.
한 외국형님은 많이 화가 나셨는지 이런 포스팅도 올렸다. (suc..? zㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ)
https://orkhanhuseyn.medium.com/why-vuetifys-native-validation-sucks-47094d621734
(말미에는 다른 라이브러리 쓰라고 아예 알려줬다. 내가 말했던 결론과 비슷하다.)
차라리 라이브러리를 사용할 수 있도록 Vuelidate 혹은 Vee-validate라는 툴을 제공해주긴하는데... 이것도 그렇게 편한건 아닌듯해서, vuetify를 쓰는 만큼 어느정도의 타협이 필요해보였다. 귀찮더라도 :error_message를 통해서 에러메세지를 처리하게하는 게 더 좋아보인다. 😥
도움이 많이됬던 링크들
[VueJS] Vuetify v-text-field 유효성 검사 (rules)
https://stackoverflow.com/questions/49132167/how-to-validate-vuetify-text-field-asynchronously
'FrontEnd > Vue' 카테고리의 다른 글
Vue props을 임의로 바꾸면 생기는 일 (0) | 2021.11.07 |
---|