初めに
カスタムルールはコンポーネントごとに定義するのではなく、使い回すことで工数やメンテナンス性を向上させることが基本です。
今回はバリデーションを特定のファイルで宣言し、各コンポーネントで使用できるようにしました。
ルールの適用
main.jsでvee-validateからdefineRuleとconfigureをimportします
import { defineRule, configure } from "vee-validate";
インポートしたすべてのルールを使用可能にするためにdefineRuleを定義
Object.keys(AllRules).forEach((rule) => {
if (rule === "default") {
return;
}
defineRule(rule, AllRules[rule]);
});
AllRulesオブジェクトの各キー(各バリデーションルールの名前)を取得し、それぞれのルールをdefineRule関数を使って定義しています。ただし、"default"という名前のルールを定義するとエラーになるので除く必要がある。なぜエラーになるのか引き続き調査する
defineRuleにカスタムルールを定義
特定のルールの作成はオブジェクトとして変数に格納する。複数作成の場合はカンマ区切り
const customRules = {
fullWidthChar: (value) =>
!/^([\p{Script=Han}|\p{Script=Hiragana}|\p{Script=Katakana}]|\u30FC)*$/u.test(
value
)
? "全角の漢字、ひらがな、カタカナ、ハイフンを入力してください"
: true,
alphaNumOrFullWidthChar: (value) =>
!/^([A-Za-z0-9-\x20]|\u30FC|\p{Script=Han}|\p{Script=Hiragana}|\p{Script=Katakana})*$/u.test(
value
)
? "半角英数字(ハイフン・スペース含む)または全角(漢字・ひらがな・カタカナ・ハイフン)を入力してください"
: true,
}
defineRuleを使って、vee-validateにカスタムルールを定義
for (const [ruleName, callback] of Object.entries(customRules)) {
defineRule(ruleName, callback);
}
この関数は、第一引数としてルールの名前、第二引数として実際のバリデーションロジックを持った関数を受け取り、そのルールを定義している。
customRulesオブジェクトのエントリ([key, value]のペア)を取得し、後続のfor-ofループで、オブジェクトの各エントリに対して処理をしている
メッセージのローカライズ
importしたconfigureで各ルールのメッセージを設定できる
configure({
generateMessage: localize("ja", {
fields: {
inputAmount: {
max_value: "残高が不足しています",
},
},
names: {
inputNumber: "クレジットカード番号",
inputExp: "有効期限",
},
messages: {
required: "{field}は必須項目です",
min_value: "0:{min}より大きい値を入力してください",
},
}),
});
names
keyにname属性、valueに項目の説明を記述することでlabelを設定できる
messages
vee-validateのデフォルトルールを上書きしたい場合は、keyにルール名、valueにエラーメッセージを記述する
fields
エラーメッセージは定義済だか、特定のフィールドにだけ異なるエラーメッセージを表示したい場合に必要。
inputAmountはnamee属性、max_valueはルール名でvalueにメッセージを記述して上書きしている
使用方法
ruleに定義したバリデーションnameを設定するだけです。
customRulesに定義したalphaNumOrFullWidthCharの使用例は以下になります。
<Field
...
name="inputAddress"
rules="alphaNumOrFullWidthChar"
/>
また、フィールドに関連するエラーメッセージはerrors.フィールド名を使用してアクセスできます。
例えば、フィールド名が "username" の場合、対応するエラーメッセージには errors.usernameでアクセスします。
以下のように
コンポーネント内でv-slotを使用し、errorsオブジェクトを受け取ることで、これらのエラーメッセージにアクセスし、表示することができます:
<Form ... v-slot="{ errors }">
<!-- フォームの内容 -->
<span>{{ errors.username }}</span> <!-- 例:'username' フィールドのエラーメッセージ -->
Formで@invalid-submitを使えばバリデーションに失敗したときにトリガーされます。
@submit イベントは、フォームが正常にバリデーションを通過したとき(すべてのフィールドが検証ルールを満たしたとき)にトリガーされます