Nuxt.js+Vuetifyで、アカウント登録画面を実装しました。
フロントで最低限の入力チェックが通ったら、送信ボタンを押せるようにして、無駄なAPIリクエスト減らす。APIからの入力エラーもvee-validateを使用して、各項目に表示するようにしました。
合わせて、前回実装したログイン画面にも導入しました。
→ Nuxt.jsとRailsアプリのDevise Token Authを連携させて認証する
初期表示

フロントの入力エラー

APIからの入力エラー

API通信エラー

vee-validate追加
$ yarn add vee-validate
アカウント登録画面
pages/users/sign_up.vue を作成
<template>
<validation-observer v-slot="{ invalid }" ref="observer">
v-slotのinvalid: 下のv-btnのdisabledで使用。ボタンを押せるか否か。
refのobserver: 下のthis.$refs.observer.setErrorsで使用。
<Message :alert="alert" :notice="notice" />
自作components → https://dev.azure.com/nightonly/nuxt-app-origin/_git/nuxt-app-origin/commit/8d6b7cb6c61470697cc9b5bc4a479aaa84e8b3a2
<v-card max-width="480px">
<v-form>
<v-card-title>
アカウント登録
</v-card-title>
<v-card-text>
<validation-provider v-slot="{ errors }" name="name" rules="required">
<v-text-field
v-model="name"
label="氏名"
prepend-icon="mdi-account"
:error-messages="errors"
/>
</validation-provider>
v-slotのerrors: error-messagesに渡されて、表示される。
rules: 入力チェック(validate)内容。
<validation-provider v-slot="{ errors }" name="email" rules="required|email">
<v-text-field
v-model="email"
label="メールアドレス"
prepend-icon="mdi-email"
:error-messages="errors"
/>
</validation-provider>
<validation-provider v-slot="{ errors }" name="password" rules="required|min:8">
<v-text-field
v-model="password"
type="password"
label="パスワード [8文字以上]"
prepend-icon="mdi-lock"
append-icon="mdi-eye-off"
:error-messages="errors"
/>
</validation-provider>
<validation-provider v-slot="{ errors }" name="password_confirmation" rules="required|confirmed:password">
<v-text-field
v-model="password_confirmation"
type="password"
label="パスワード(確認)"
prepend-icon="mdi-lock"
append-icon="mdi-eye-off"
:error-messages="errors"
/>
</validation-provider>
<v-btn color="primary" :disabled="invalid" @click="signUp">
登録
</v-btn>
</v-card-text>
<v-card-actions>
<ul>
<li>
<NuxtLink to="/users/sign_in">
ログイン
</NuxtLink>
</li>
</ul>
</v-card-actions>
</v-form>
</v-card>
</validation-observer>
</template>
<script>
import { required, email, min, confirmed } from 'vee-validate/dist/rules'
import { extend, ValidationObserver, ValidationProvider, setInteractionMode } from 'vee-validate'
import Message from '~/components/Message.vue'
setInteractionMode('eager')
eager(デフォルト)かlazy
> フォーカスアウト時にバリデーションが走り、エラーの場合は、エラーが消えるまで入力中でも、バリデーションが走る
VeeValidateのバリデーション発火タイミングを変更する方法 | ガクLog
extend('required', {
...required,
message: '入力してください。'
TODO: vee-validateのlocale使うか、vue-i18nを使った方が良さそう。
→ publicRuntimeConfigで環境毎の値を保持とi18n対応
})
extend('email', {
...email,
message: '形式が正しくありません。'
})
extend('min', {
...min,
message: '{length}文字以上で入力してください。'
})
extend('confirmed', {
...confirmed,
message: 'パスワードと一致しません。'
})
export default {
name: 'UsersSignUp',
> nameプロパティをつける理由は、(1)処理の中でそのデータ(値)を使うから。
> あるいは、(2)デバッグ用として。
【Vue】export defaultのnameについて – Qiita
components: {
ValidationObserver,
ValidationProvider,
Message
},
data () {
return {
alert: null,
notice: null,
name: '',
email: '',
password: '',
password_confirmation: ''
}
},
created () {
if (this.$auth.loggedIn) {
this.$toasted.info('既にログインしています。')
return this.$router.push({ path: '/' })
}
「middleware: ‘auth’」でも出来ますが、メッセージ出す為。
toast便利ですね。下記で追加。
$ yarn add @nuxtjs/toast
},
methods: {
async signUp () {
await this.$axios.post('http://localhost:3000/users/auth/sign_up.json', {
TODO: URLは環境毎に変わるので、cross-envを使った方が良さそう。
→ publicRuntimeConfigで環境毎の値を保持とi18n対応
name: this.name,
email: this.email,
password: this.password,
password_confirmation: this.password_confirmation,
confirm_success_url: 'http://localhost:5000/users/sign_in'
})
.then((response) => {
return this.$router.push({ path: '/users/sign_in', query: { alert: response.data.alert, notice: response.data.notice } })
成功時は、パラメータでメッセージ渡して、ログイン画面で表示して貰う。
},
(error) => {
if (error.response == null) {
前回は、(typeof error.response === ‘undefined’)を使っていたけど、これに変更。
===(3つ)にするとfalseになるので、==(2つ)
this.$toasted.error('通信に失敗しました。しばらく時間をあけてから、やり直してください。')
} else {
this.alert = error.response.data.alert
this.notice = error.response.data.notice
this.$refs.observer.setErrors(error.response.data.errors)
APIからの入力エラーをsetErrorsで渡してあげるだけで表示される。
observer: 上のvalidation-observerのrefで定義。
}
return error
})
}
}
}
</script>
ログイン画面
初期表示

フロントの入力エラー

APIからの入力エラー

認証成功


“vee-validateで入力チェックした上で、APIからの入力エラーも各項目に表示する” に対して1件のコメントがあります。