Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
VeeValidateによるフォームバリデーションの実装
Search
YRyu
May 15, 2024
Programming
0
160
VeeValidateによるフォームバリデーションの実装
NuxtプロジェクトにVeeValidateを導入し、フォームバリデーションを実装する手順を紹介します。
YRyu
May 15, 2024
Tweet
Share
Other Decks in Programming
See All in Programming
iOSアプリ開発で 関数型プログラミングを実現する The Composable Architectureの紹介
yimajo
2
220
Node-RED を(HTTP で)つなげる MCP サーバーを作ってみた
highu
0
100
Julia という言語について (FP in Julia « SIDE: F ») for 関数型まつり2025
antimon2
3
980
GitHub Copilot and GitHub Codespaces Hands-on
ymd65536
1
120
PHPでWebSocketサーバーを実装しよう2025
kubotak
0
220
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
1
570
システム成長を止めない!本番無停止テーブル移行の全貌
sakawe_ee
1
140
設計やレビューに悩んでいるPHPerに贈る、クリーンなオブジェクト設計の指針たち
panda_program
6
1.6k
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
280
すべてのコンテキストを、 ユーザー価値に変える
applism118
2
880
プロダクト志向ってなんなんだろうね
righttouch
PRO
0
160
エンジニア向け採用ピッチ資料
inusan
0
160
Featured
See All Featured
Code Review Best Practice
trishagee
68
18k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
20
1.3k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
281
13k
Intergalactic Javascript Robots from Outer Space
tanoku
271
27k
Visualization
eitanlees
146
16k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
670
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
46
9.6k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.8k
Testing 201, or: Great Expectations
jmmastey
42
7.5k
We Have a Design System, Now What?
morganepeng
53
7.7k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Transcript
VeeValidateによる フォームバリデーションの実装 @YRyu
⽬次 1. はじめに 2. 開発環境 3. フォーム作成 4. VeeValidate導⼊ 5.
バリデーション実装 6. 送信時のボタン制御 7. エラー箇所へスクロール 8. おわりに 2
はじめに VeeValidateとは... フォーム実装に必要な機能を兼ね備えたVue向けのモジュール - Form state and value tracking -
UX - Synchronous and Asynchronous Validation - Handling submissions 3
開発環境 node : 18.18.2 npm : 8.19.3 nuxt : 3.11.2
vee-validate : 4.12.6 yup : 1.4.0 ✓ VeeValidateはv3からv4へのメジャーアップデートで⼤きく仕様が変更されました ✓ Yupはバリデーションスキーマを定義するJSモジュールです 4
フォーム作成 Nuxtを⽤いてプロジェクトを作成し、基本的なログイン機能の実装を⾏う 5 interface LoginBody { email: string password: string
} export default defineEventHandler(async (event) => { const body = await readBody<LoginBody>(event) if (body.email === '
[email protected]
' && body.password === 'password') { return '認証に成功しました。 ' } else { throw createError('認証に失敗しました。 ') } }) /server/api/login.post.ts
Nuxtを⽤いてプロジェクトを作成し、基本的なログイン機能の実装を⾏う フォーム作成 <template> <h1>ログインページ </h1> <form @submit.prevent="submit()"> <input v-model="formData.email" type="email"
name="email" placeholder="メールアドレス " /> <input v-model="formData.password" type="password" name="password" placeholder="パスワード" /> <button>ログイン</button> <span v-if="errorMessage">{{ errorMessage }}</span> </form> </template> 6 /pages/login.vue <script setup lang="ts"> const formData = ref({ email: '', password: '' }) const errorMessage = ref('') const submit = async () => { const { error } = await useFetch('/api/login', { method: 'POST', body: formData.value }) if (error.value) { errorMessage.value = error.value.data.message || '予期せぬエラーが発生しました。 ' } else { errorMessage.value = '' navigateTo('/') } } </script>
1. VeeValidateとYupのインストールを⾏う > npm i vee-validate yup VeeValidate導⼊ 7
2. VeeValidateのComposition APIを使って、作成したフォームを書き換える VeeValidate導⼊ 8 + const submit = handleSubmit(
+ async (values) => { + const { error } = await useFetch('/api/login', { + method: 'POST', + body: values + }) + if (error.value) { + errorMessage.value = error.value.data.message + || '予期せぬエラーが発生しました。 ' + } else { + errorMessage.value = '' + navigateTo('/') + } + } + ) </script> /pages/login.vue <script setup lang="ts"> + import { useForm, useField } from 'vee-validate' - const formData = ref({ email: '', password: '' }) + const { handleSubmit } = useForm() + const { value: email } = useField('email') + const { value: password } = useField('password') const errorMessage = ref('') - const submit = async () => { - const { error } = await useFetch('/api/login', { - method: 'POST', - body: formData.value - }) - if (error.value) { - errorMessage.value = error.value.data.message - || '予期せぬエラーが発生しました。 ' - } else { - errorMessage.value = '' - navigateTo('/') - } - }
2. VeeValidateのComposition APIを使って、作成したフォームを書き換える VeeValidate導⼊ <template> <h1>ログインページ </h1> <form @submit.prevent="submit()"> -
<input v-model="formData.email" type="email" name="email" placeholder="メールアドレス " /> + <input v-model="email" type="email" name="email" placeholder="メールアドレス " /> - <input v-model="formData.password" type="password" name="password" placeholder="パスワード" /> + <input v-model="password" type="password" name="password" placeholder="パスワード" /> <button>ログイン</button> <span v-if="errorMessage">{{ errorMessage }}</span> </form> </template> 9 /pages/login.vue
バリデーション実装 Yupのバリデーションスキーマを使って、フォームにバリデーションを追加する 10 <script setup lang="ts"> import { useForm, useField
} from 'vee-validate' + import { string } from 'yup' - const { handleSubmit } = useForm() + const { handleSubmit } = useForm({ + validationSchema: { + email: string().email().required(), + password: string().min(8).max(16).required() + } + }) - const { value: email } = useField('email') + const { value: email, errorMessage: emailError } = useField('email') - const { value: password } = useField('password') + const { value: password, errorMessage: passwordError } = useField('password') const errorMessage = ref('') const submit = handleSubmit( async (values) => { const { error } = await useFetch('/api/login', { method: 'POST', body: values }) if (error.value) { errorMessage.value = error.value.data.message || '予期せぬエラーが発生しました。 ' } else { errorMessage.value = '' navigateTo('/') } - } + }, + () => { + errorMessage.value = '入力内容に誤りがあります。 ' + } ) </script> /pages/login.vue
バリデーション実装 Yupのバリデーションスキーマを使って、フォームにバリデーションを追加する 11 <template> <h1>ログインページ </h1> <form @submit.prevent="submit()"> <input v-model="email"
type="email" name="email" placeholder="メールアドレス " /> + <span v-if="emailError">{{ emailError }}</span> <input v-model="password" type="password" name="password" placeholder="パスワード" /> + <span v-if="passwordError">{{ passwordError }}</span> <button>ログイン</button> <span v-if="errorMessage">{{ errorMessage }}</span> </form> </template> /pages/login.vue
フォーム送信時にボタンの制御を⾏う 送信時のボタン制御 12 <script setup lang="ts"> import { useForm, useField
} from 'vee-validate' import { string } from 'yup' - const { handleSubmit } = useForm({ + const { handleSubmit, isSubmitting } = useForm({ validationSchema: { email: string().email().required(), password: string().min(8).max(16).required() } }) const { value: email, errorMessage: emailError } = useField('email') const { value: password, errorMessage: passwordError } = useField('password') const errorMessage = ref('') const submit = handleSubmit( /* 省略 */ ) </script> <template> <h1>ログインページ </h1> <form @submit.prevent="submit()"> <input v-model="email" type="email" name="email" placeholder="メールアドレス " /> <span v-if="emailError">{{ emailError }}</span> <input v-model="password" type="password" name="password" placeholder="パスワード" /> <span v-if="passwordError">{{ passwordError }}</span> - <button>ログイン</button> + <button :disabled="isSubmitting"> + {{ isSubmitting ? 'ログイン中...' : 'ログイン' }} + </button> <span v-if="errorMessage">{{ errorMessage }}</span> </form> </template> /pages/login.vue
エラー箇所へスクロール 検知したバリデーションエラーの発⽣箇所へスクロールさせる 13 <script setup lang="ts"> import { useForm, useField
} from 'vee-validate' import { string } from 'yup' const { handleSubmit, isSubmitting } = useForm({ validationSchema: { email: string().email().required(), password: string().min(8).max(16).required() } }) const { value: email, errorMessage: emailError } = useField('email') const { value: password, errorMessage: passwordError } = useField('password') const errorMessage = ref('') const submit = handleSubmit( async (values) => { /* 省略 */ }, - () => { + ({ errors }) => { errorMessage.value = '入力内容に誤りがあります。 ' + document.querySelector( + `input[name="${Object.keys(errors)[0]}"]` + )?.scrollIntoView({ + behavior: 'smooth' + }) } ) </script> /pages/login.vue
おわりに VeeValidateを⽤いることで、以下の機能を簡単に実装することができた - バリデーションの実装 - エラーメッセージの表⽰ - 送信ボタンの制御 - エラー箇所へのスクロール
また、Composition APIを使った実装により、カスタムコンポーネントへの拡張 性も⾮常に⾼いと感じた 14
参考 [1] https://nuxt.com/docs/getting-started/introduction [2] https://vee-validate.logaretm.com/v4/guide/overview/ [3] https://github.com/jquense/yup 15