5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VeeValidateでラジオ・チェック・セレクトボックスのバリデーションをする

Posted at

本年6月から、マイホムにジョインしましたkokoeです。わっしょい。
そして、こちらは株式会社マイホム Advent Calendar 2021 6日目の記事です♪(あれっ。。間があいてる)

最近、VeeValidateを使ってフォームバリデーションを実装していたのですが、
ラジオ・チェック・セレクトボックスのバリデーションにつまづいたもんで、解決した方法をメモがてら書きのこしていきたいと思います。

前提

以下のバージョンで確認しています。

  • VeeValidate v3
  • Vue.js v2

ラジオボックス・チェックボックスの必須バリデーションができない!

required allowFalse=false を指定します。
https://vee-validate.logaretm.com/v3/guide/rules.html#required

<ValidationProvider
  vid="foo-checkbox"
  :rules="{ required: { allowFalse: false } }"
>
  <input type="checkbox" v-model="foo" />
</ValidationProvider>

セレクトボックスの必須バリデーションができない!

必須=デフォルト値以外、という意図で使っています。

デフォルト値が空のケース

skip-if-empty=falseを指定します。
https://vee-validate.logaretm.com/v3/api/validation-provider.html#props

<ValidationProvider
  vid="foo-select"
  rules="required"
  :skip-if-empty="false"
>
  <select v-model="selectValue">
    <option value="">-- 選択 --</option>
    <option value="foo">-- foo --</option>
    <option value="bar">-- bar --</option>
  </select>
</ValidationProvider>

デフォルト値が空以外のケース

カスタムルールをつくりましょう。

import { extend } from 'vee-validate';
import type { ValidationRule } from 'vee-validate/dist/types/types';

/**
 * セレクトボックス required
 * required_select:${defaultValue},${defaultValueType} を指定
 *
 * @example
 * この例では、0がデフォルト値で、0をnumber型に変換した値でvalue値と比較する
 * <ValidationProvider rules="required_select:0,number"></ValidationProvider>
 */
const required_select: ValidationRule = {
  validate(
    value: unknown,
    params: [unknown, 'string' | 'number' | 'boolean']
  ) {
    // params[0]:デフォルト値。valueがデフォルト値なら invalid
    const defaultValue = Array.isArray(params) ? params[0] : '';
    // params[1]:デフォルト値の型指定(paramsはstring[]なので)
    const dataType = Array.isArray(params) ? params[1] || 'string' : 'string';

    const formattedDefaultValue = (() => {
      switch (dataType) {
        case 'number':
          return Number(defaultValue);
        case 'boolean':
          return Boolean(defaultValue);
        default:
          return defaultValue;
      }
    })();

    return value !== formattedDefaultValue;
  },
  message: '{_field_}を選択してください'
};

extend('required_select', required_select);

valueを文字列で扱う

<ValidationProvider
  v-slot="{ errors }"
  vid="foo"
  name="foo select"
  rules="required_select:none,string"
>
  <select v-model="selectValue">
    <option value="none">-- 選択 --</option>
    <option value="foo">-- foo --</option>
    <option value="bar">-- bar --</option>
  </select>
  <p>{{ errors[0] }}</p>
</ValidationProvider>

valueを数値で扱う

<ValidationProvider
  v-slot="{ errors }"
  vid="foo"
  name="foo select"
  rules="required_select:0,number"
>
  <select v-model.number="selectValue">
    <option value="0">-- 選択 --</option>
    <option value="1">-- foo --</option>
    <option value="2">-- bar --</option>
  </select>
  <p>{{ errors[0] }}</p>
</ValidationProvider>

おわり

使い方覚えると、かなりのバリデーションパターンに対応できてほんとに便利です。
また、次のアドベントカレンダーネタもVeeValidateでいこうかな。

ご覧いただきありがとうございました。ぺこり。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?