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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
YRyu
May 15, 2024
Programming
0
200
VeeValidateによるフォームバリデーションの実装
NuxtプロジェクトにVeeValidateを導入し、フォームバリデーションを実装する手順を紹介します。
YRyu
May 15, 2024
Tweet
Share
Other Decks in Programming
See All in Programming
ポーリング処理廃止によるイベント駆動アーキテクチャへの移行
seitarof
3
1.1k
メタプログラミングで実現する「コードを仕様にする」仕組み/nikkei-tech-talk43
nikkei_engineer_recruiting
0
190
Agentic AI: Evolution oder Revolution
mobilelarson
PRO
0
180
AI時代のシステム設計:ドメインモデルで変更しやすさを守る設計戦略
masuda220
PRO
5
1k
AWS×クラウドネイティブソフトウェア設計 / AWS x Cloud-Native Software Design
nrslib
16
3.2k
モジュラモノリスにおける境界をGoのinternalパッケージで守る
magavel
0
3.6k
受け入れテスト駆動開発(ATDD)×AI駆動開発 AI時代のATDDの取り組み方を考える
kztakasaki
2
590
Windows on Ryzen and I
seosoft
0
300
Cyrius ーLinux非依存にコンテナをネイティブ実行する専用OSー
n4mlz
0
160
TipKitTips
ktcryomm
0
170
コーディングルールの鮮度を保ちたい / keep-fresh-go-internal-conventions
handlename
0
200
Claude Codeセッション現状確認 2026福岡 / fukuoka-aicoding-00-beacon
monochromegane
4
430
Featured
See All Featured
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
110
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
64
53k
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.8k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
440
Making the Leap to Tech Lead
cromwellryan
135
9.8k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
200
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
1
160
Tell your own story through comics
letsgokoyo
1
850
Crafting Experiences
bethany
1
89
sira's awesome portfolio website redesign presentation
elsirapls
0
190
HDC tutorial
michielstock
1
550
So, you think you're a good person
axbom
PRO
2
2k
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