vee-validateをvue3で使う

 以下の記事はアメブロで2025-06-26に投稿したものです。


ちょっと使いたいだけのなのに、
ドキュメントが英語だったり
ComponentsとCompositionAPI(コンポーサブル)とに分かれていて
どっちが使いやすいのか、どういうメリット/デメリットがあるのかすぐにはよく分からない。

どうもコンポーサブルのほうが自由度が高いようだし
どちらというと公式ドキュメントもコンポーサブルを押しているようなので(Imperative vs Declarative)、
こちらを使うことにした。
どころがこちらもuserForm()だのuseField()だのあるし、
さらにdefineField()なんてもあるので、どれを使うとよいのかハテとなった。
なので、忘れないように、ここに覚え書きしようと思う。

以下のコードは公式ドキュメントを以下のようにたどると出てくる。
https://vee-validate.logaretm.com/v4/ ===> Get Started ===> Composition API ===> Custom inputs
ここ(Building Custom inputs)編集可能サンプルの最初のサンプルソースを改変したものだ。
青字が変更箇所
コピペする場合はA0(ノーブレークスペース)から20(スペース)へ変換する必要があるかも、、、
アメブロってなんで20じゃないんだろ??

App.vue
<template>
  <form @submit="onMySubmit">
    <InputText name="firstName" />
    <InputText name="lastName" />
    <InputText name="email" type="email" />
    <InputText name="password" type="password" />
    <InputText name="passwordConfirm" type="password" />

    <button>Submit</button>
  </form>
</template>

<script setup>
import { useForm } from 'vee-validate';
import * as yup from 'yup';
import InputText from './InputText.vue';

const { errors, validate, values, meta } = useForm({
  validationSchema: yup.object({
    firstName: yup.string().required().min(1),
    lastName: yup.string().required().min(2),
    email: yup.string().required().email(),
    password: yup.string().required().min(6),
    passwordConfirm: yup
      .string()
      .required()
      .min(6)
      .oneOf([yup.ref('password')]),
  }),
});

const onMySubmit = async (event) => {
  event.preventDefault();
  await validate();
  console.log('onMySS meta', meta.value)
  console.log('onMySS errors', errors.value)
  console.log('onMySS values', Object.keys(values))
  console.log('onMySS values2', values)
};
</script>

InputText.vue
<template>
  <input v-model="value" :type="'text'" />
  <ul v-if="errors.length">
    <li v-for="error in errors">{{ error }}</li>
  </ul>
</template>

<script setup>
import { useField } from 'vee-validate';

const props = defineProps({
  name: String,
  type: String,
});

// The `name` is returned in a function because we want to make sure it stays reactive
// If the name changes you want `useField` to be able to pick it up
const { value, errors } = useField(() => props.name, undefined, {validateOnValueUpdate: false});
</script>

これでSubmitボタンを押すまでバリデーションチェックは表示されないし(どうも裏でバリデーション自体は動いているようだけど)
バリデーションが成功しても失敗してもonMySubmitが呼ばれる。
InputText.vueのinput-typeを修正したのは、typeがemailだとブラウザのバリデーションチェックが動いてしまってやっかいだからだ。
つまり、バリデーションチェックはvee-validateだけで行いたいのだ。

これをベースに色々やればよさそうだが、入力項目が動的に増減する場合は、
これではダメでuseFieldArray()を使う必要があるようだ。
https://vee-validate.logaretm.com/v4/ ===> Get Started ===> Composition API ===> Nested Objects and Arrays ===> Field Arrays
ここのサンプルがよさげだ。
<Field />コンポーネントを使ったサンプルはuseFieldArray APIの説明にある。

ちなみに編集可能なサンプルだが
この赤丸をクリックすると
別ウィンドウが開くので、
開いた先のにこの赤丸をクリックすると
実行環境の別ウィンドウが開くので、
赤丸を押下すると
こうなって、F12を押下してデバッグウィンドウを開けば、console.logも見れる。
途中で自動ビルドが動かなくなったりすることがあるようだけど、
stackblitz.comのコンソールウィンドウでnpm run devとたたけば復活する。







コメント