今まで入力フォームのバリデーション使うのにVeeValidate使ってたんですが、Nuxt v2に組み込んだ時うまい事動いてくれなかったので、これを機にVuelidateに変えてみました。
環境
Nuxt v2.2.0
Vuelidate v0.7.4
Vuetify v1.3.5
Install
$ yarn install vuelidate
Setup
import Vue from 'vue'
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)
module.export = {
plugins: ['@/plugins/vuelidate']
}
Using(Example)
dataプロパティの中身を見て、自動的にVuelidateを発火させるようv-model="$v.{data}.$model"
にしてv-modelと紐付けてます。
自分のタイミングでバリデーションかけたい場合は、v-model="{data}"
にして、発火したいタイミングでthis.$v.{data}.$touch()
すると良いです。
<template>
<v-container>
<v-layout justify-center>
<v-flex xs12 sm8>
<v-toolbar color="primary" dark>
<v-toolbar-title>ログイン</v-toolbar-title>
</v-toolbar>
<v-card>
<v-container fluid>
<v-form ref="form">
<v-layout row wrap>
<v-text-field type="email" v-model="$v.email.$model" label="メールアドレス" required :error-messages="emailErrors"></v-text-field>
</v-layout>
<v-layout row wrap>
<v-text-field type="password" v-model="$v.password.$model" label="パスワード" required :error-messages="passwordErrors"></v-text-field>
</v-layout>
<v-layout row wrap justify-center>
<v-btn block color="success" @click="signIn()">ログイン</v-btn>
</v-layout>
</v-form>
</v-container>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import { required, email } from 'vuelidate/lib/validators'
import { validateEmail, validatePassword } from '~/utils/validations'
export default {
head() {
return {
title: 'ログイン'
}
},
data: () => ({
email: '',
password: ''
}),
validations: {
email: {
required,
email
},
password: {
required
}
},
computed: {
emailErrors() {
return validateEmail(this.$v.email)
},
passwordErrors() {
return validatePassword(this.$v.password)
}
},
methods: {
async signIn() {
// validation発火
this.$v.$touch()
// validationに引っかかってるか検査
if (this.$v.$invalid) return
// このあとサインイン処理
}
}
}
</script>
export const validateEmail = validate => {
let errors = []
if (!validate.$dirty) return errors
!validate.required && errors.push('メールアドレスを入力してください')
!validate.email && errors.push('メールアドレスの形式で入力してください')
return errors
}
export const validatePassword = validate => {
let errors = []
if (!validate.$dirty) return errors
!validate.required && errors.push('パスワードを入力してください')
return errors
}
Validationメッセージ共通化させたかったのでutils
作ったんですが、もっといい方法ないかなーって思ってます(知識不足)。
一応、他にもいろいろバリデーションの形式があるので、よかったら公式ドキュメント見てみてください。
Builtin validators
最後に
VeeValidateのほうがGitHubのスター数とか多いですが、思ったより素直に書けたので、このまま使ってみます。
ただ、VeeValidateのdictionary
が個人的に好きなので、Vuelidateでもあんな感じなのないかなーって思ってます。
もしVuelidate使ってて、もっといい方法知ってる人がいたら、ぜひ教えてください🙌