vee-validateにさわる

vee-validateはバリデーション処理を行うためのライブラリ。

インストール

yarn add vee-validate@next
yarn add yup

※yupは必須チェックや桁数チェックなど、チェック処理をまとめたライブラリ

Element+と組み合わせて使う

バリデーションは、各項目へのバリデーション処理をルールとして、schemaという形で定義し、それに従ってチェックを行う。

<template lang="pug">
Form(as="el-form" :validation-schema="schema" :initialValues="formModel" @submit="onSubmit")
  Field(name="email" v-slot="{ value, field, errorMessage }")
    el-form-item(label="Email Address" :error="errorMessage")
      el-input(
        placeholder="Email Address"
        name="email"
        clearable
        v-bind="field"
        :model-value="value"
      )
  Field(name="url" v-slot="{ value, field, errorMessage }")
    el-form-item(label="Url" :error="errorMessage")
      el-input(
        placeholder="Url"
        name="url"
        v-bind="field"
        :model-value="value"
      )
        template(#prepend) Http://
  Field(name="password" v-slot="{ value, field, errorMessage }")
    el-form-item(label="Password" :error="errorMessage")
      el-input(
        placeholder="Password"
        name="password"
        show-password
        v-bind="field"
        :model-value="value"
      )
  Field(name="freeword" v-slot="{ value, field, errorMessage }")
    el-form-item(label="Freeword" :error="errorMessage")
      el-input(
        placeholder="Input freeword"
        name="freeword"
        v-bind="field"
        :model-value="value"
      )
        template(#prepend)
          Field(name="freewordType" v-slot="{ value, field, errorMessage }")
            el-select(
              placeholder="Select"
              name="freewordType"
              style="width: 120px;"
              v-bind="field"
              :model-value="value"
            )
              el-option(label="" value="")
              el-option(label="Address" value="1")
              el-option(label="Name" value="2")
              el-option(label="E-Mail" value="3")
  Field(name="choice" v-slot="{ value, field, errorMessage }")
    el-form-item(label="Select" :error="errorMessage")
      el-select(
        name="choice"
        v-bind="field"
        :model-value="value"
      )
        el-option(label="OK" value="ok")
        el-option(label="NG" value="ng")

  Field(name="checkA" type="checkbox" :value="true" :unchecked-value="false" v-slot="{ value, errorMessage, handleChange }")
    el-form-item(label="CheckBoxA" :error="errorMessage")
      el-checkbox(
        name="checkA"
        :model-value="value"
        @update:model-value="handleChange"
      )
        p 同意する場合はチェックしてください

  Field(name="radioA" v-slot="{ value, field, errorMessage }")
    el-form-item(label="Radio" :error="errorMessage")
      el-radio(label="a" v-bind="field" :model-value="value")
      el-radio(label="b" v-bind="field" :model-value="value")

  el-button(type="primary" native-type="submit") Submit
</template>

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

// https://element-plus.org/#/en-US/component/form
export default defineComponent({
  name: "FormValidationPage",
  components: {
    Form,
    Field,
  },
  setup() {
    const formModel = reactive({
      email: "a@b.c",
      password: "abcdefghijk",
      url: "http://www.google.com/",
      age: 0,
      freeword: "",
      freewordType: "",
      choice: "",
      checkA: false,
      radioA: "",
    });

    const schema = yup.object({
      email: yup.string().required().email().label("Email address"),
      url: yup.string().required().url().label("URL"),
      password: yup.string().required().min(6).label("Password"),
      // https://www.techzaion.com/validation-with-yup
      // https://blog.devgenius.io/form-validation-in-a-vue-3-app-with-vee-validate-4-yup-schemas-radio-buttons-and-checkboxes-c0068d151ae2
      freeword: yup
        .string()
        .when('freewordType', {
          is: (freewordType: string) => freewordType !== "",
          then: yup.string().required() 
        })
        .when('freewordType', {
          is: (freewordType: string) => freewordType === "",
          then: yup.string().matches(/^$/, {message: "Select Type."}) 
        })
        .label("Freeword"),
      choice: yup.string().required().label("Choice"),
      checkA: yup
        .boolean()
        .required()
        .isTrue("You must check on.")
        .label("Check A"),
      radioA: yup.string().required().label("Radio A"),
    });

    function onSubmit(values: any, actions: any) {
      console.log("#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_");
      console.log(JSON.stringify(values, null, 2));
      console.log(formModel);
      actions.resetForm();
    }
    return {
      onSubmit,
      schema,
      formModel,
    };
  },
});
</script>