初めてのVueで初めてのVeeValidateだったのでめちゃくちゃ苦労した・・・。あまり日本語の参考サイトも見当たらなかったので書いておきます。
具体的なコードはそのまま載せられないので、僕が「そういう風に書くのか!」と思ったポイントを書きます。
画面のイメージ
考え方を紹介するにしても、どんな画面かをイメージできないといけないですね。僕がイメージしている画面はテキストの入力欄が追加ボタンを押したら増えていく画面です。
例えば自分が持っているチケット番号の入力欄を増やせて一気に複数入力できるような画面です。
動的に増える項目をVeeValidateでどうやって書くか
ValidationProviderタグにv-forを書いてループさせます。
↓のような感じです。(rulesは省略しています。)
tag=”li”でValidationProviderのタグがliタグで出力されます。
<ValidationProvider
v-bind:name="ticket.code + '-' + index"
v-slot="{ errors }"
v-for="(ticket, index) in form.ticketList" :key="ticket.id" tag="li">
データの持ち方は以下のように持っています。
ticket_input_idxはexport defaultの外側でlet ticket_input_idx = 0をしています。
ボタンを押して入力欄を増やすfunctionを別で用意して、ticketListにid,codeのオブジェクトを追加していきます。その際にカウント(ticket_input_idx)を増やしています。
form: {
ticketList: [
{
id: ticket_input_idx,
code: '',
}
],
}
気をつけること
一つ目はv-bind:nameで入力欄ごとに違う値にすることです。
これが同じ値になっているとバリデーションが正しく動かないところが出てきます。
※今思えば、v-bindのところでticket.code〜と書いていますが、ticket.idとすれば文字列連結でindexを付けなくてもよかったのかもしれないです。
二つ目は上記のサンプルコードだとValidateProviderでv-forを使用していますが、僕が実際に書いたコードではさらにrulesで条件分岐が入っていました。
※動的なバリデーションのサンプルは公式↓にあります。
ValidateProviderのv-forに条件分岐の処理を入れると動作が遅くなるのか、一瞬バリデーションがtrueの動きをしてからエラーメッセージが出るようになりました。(どこかのWebページでv-forとv-ifを一緒に使うのは推奨しないと書かれていたので、どうしても遅くなるのかもしれません)
コメント