vue3 + yup + vee-validate4 のフォームサンプル

npm i vee-validate@next --save
npm i yup

● vee-validate を使ってみる

<script lang="ts" setup>
import { Form, Field, ErrorMessage } from "vee-validate";
import * as yup from "yup";

const schema = yup.object({
  password: yup.string().required().min(4),
  sortNo: yup.number(),
});

function getSubmitFn<Schema extends yup.ObjectSchema<Record<string, any>>>(
  _: Schema,
  callback: (values: yup.InferType<Schema>) => void
) {
  return (values: Record<string, any>) => {
    return callback(values);
  };
}

const handleSubmit = getSubmitFn(schema, (value) => {
  console.log("● value");
  console.log(value);
});
</script>

<template>
  <h1>Samplepageelement</h1>
  <Form @submit="handleSubmit" v-slot="{ values }" :validation-schema="schema">
    <!-- <Form @submit="handleSubmit"> -->
    <div>
      <Field name="password" type="password" />
      <ErrorMessage name="password" style="color: #c45656" />
    </div>

    <div>
      <Field
        name="sortNo"
        type="number"
        @update:modelValue="values.sortNo = Number(values.sortNo)"
      />
      <ErrorMessage name="sortNo" style="color: #c45656" />
    </div>

    <button>送信</button>
  </Form>
</template>

結果

● value
{password: 'asdfasdfads', sortNo: 1234}

number型を期待しているsortNoがそのままだとstringで返ってきてしまうので、@update:modelValue で変換しています。

https://bit.ly/3uRxmpM. https://vee-validate.logaretm.com/v4/guide/components/validation.

● handleSubmit に 型つける

const handleSubmit = (values:any) => {
  console.log( '● value' );
  console.log( value );
};

 ↓ 以下のように書き換えます

function getSubmitFn<Schema extends yup.ObjectSchema<Record<string, any>>>(
  _: Schema,
  callback: (values: yup.InferType<Schema>) => void
) {
  return (values: Record<string, any>) => {
    return callback(values);
  };
}

const handleSubmit = getSubmitFn(schema, (value) => {
  console.log("● value");
  console.log(value);
});

引用 : https://github.com/logaretm/vee-validate/issues/3521

● vee-validate の useFormでリアクティブに値を取得する

<template>
  <div>
    <div>
      <Field name="age" as="input" type="number" />
      <div>{{ errors.age }}</div>
    </div>

    <div>
      <Field name="name" as="input" />
      <div>{{ errors.name }}</div>
    </div>

    <div>
      <Field name="password" as="input" type="password" />
      <div>{{ errors.password }}</div>
    </div>

    <pre>Is form dirty: {{ isDirty }}</pre>

    <!-- print form values -->
    <pre>{{ values }}</pre>
  </div>
</template>

<script lang="ts" setup>
import { defineComponent, computed } from 'vue'
import { Field, useForm } from 'vee-validate'
import * as yup from 'yup'

interface UserFormValues {
  age: number
  name: string
  password: string
}

const schema = yup.object().shape({
  age: yup.number().required(),
  name: yup.string().required(),
  password: yup.string().required().min(8)
})
const { meta, values, errors } = useForm<UserFormValues>({
  validationSchema: schema
})

const isDirty = computed(() => meta.value.dirty)
</script>

● バリデーションの実行タイミングを変更する

// インポートした「configure」を使用してトリガするイベントを変更
configure({
  validateOnBlur: true, // blurイベントで検証をトリガーする必要がある場合、デフォルトはtrue
  validateOnChange: true, // changeイベントで検証をトリガーする必要がある場合、デフォルトはtrue
  validateOnInput: true, // inputイベントで検証をトリガーする必要がある場合、デフォルトはfalse
  validateOnModelUpdate: true, // update:modelValue(v-model)イベントで検証をトリガーする必要がある場合、デフォルトはtrue
});

引用 : https://bit.ly/3iT9bEo

● 手動でエラーを設定する

https://vee-validate.logaretm.com/v4/guide/composition-api/handling-forms#initial-errors

● UIライブラリとともに使用する

<Field name="password" type="text" />
<ErrorMessage name="password" />

  ↓

<Field name="password" v-slot="{ value, field, errorMessage }">
  <el-form-item :error="errorMessage">
    <el-input
      v-bind="field"
      :validate-event="false"
      :model-value="value"
      type="password"
      show-password
    />
  </el-form-item>
</Field>
No.2239
12/22 15:42

edit