JavaScript
vue.js

veeValidate試行錯誤の記録(随時更新中)

日本語化

import VeeValidate from 'vee-validate'
import VeeValidateLocaleJa from 'vee-validate/dist/locale/ja'

Vue.use(VeeValidate, {
  locale: 'ja',
  dictionary: {
    ja: VeeValidateLocaleJa
  }
})

tempate側ではdata-vv-asがポイント

<input
  name="userName"
  class="input"
  type="text"
  v-model="userName"
  data-vv-as="ユーザー名"
  v-validate="'required|max:25'"/>
<p v-show="errors.has('userName')">{{ errors.first('userName') }}</p>

scope

フォームごとにコンポーネントを分割すればそもそも要らないと言えば要らないけど、
複数のフォームを別々に管理したい場合に使う
ググると結構英語圏で質問してる人が多かったので需要ありそう
下記のようにしたらうまく動いた

<form data-vv-scope="primaryForm" @submit.prevent="validatePrimary()">
  <input
    name="name"
    class="input"
    :class="{'is-danger': errors.has('primaryForm.name')}"
    type="text"
    v-validate="'required|max:255'" />
  <p v-show="errors.has('primaryForm.name')" class="help is-danger">{{ errors.first('primaryForm.name') }}</p>
</form>

<form data-vv-scope="secondaryForm" @submit.prevent="validateSecoundary()">
  <input
    name="name"
    class="input"
    :class="{'is-danger': errors.has('secondaryForm.name')}"
    type="text"
    v-validate="'required|max:255'" />
  <p v-show="errors.has('secondaryForm.name')" class="help is-danger">{{ errors.first('secondaryForm.name') }}</p>
</form>
export default {
  methods: {
    validatePrimary () {
      this.$validator.validateAll('primaryForm').then((result) => {
        if (result) {
          // 正常系
        }
      })
    },
    validateSecoundary () {
      this.$validator.validateAll('secondaryForm').then((result) => {
        if (result) {
          // 正常系
        }
      })
    },
  }
}

公式のissueに上がってたけど、formで囲んで
data-vv-scope="スコープ名"をつけることと
nameにスコープ名のプレフィックスをつけることがポイント

validatorのリセット

  • ダイヤログで登録フォームを表示する場合、成功時は入力値をクリアしたい
    • するとrequiredの場合、そこでエラーハンドリングが走ってしまいせっかく初期表示ではエラーがでていない良さを台無しにしてしまう。

回答: reset()してやれば良い

  this.textParameter = ''
  this.$validator.reset()

日付

・日付バリデーションを追加するため installDateTimeValidatorsを実行しようとすると
not a functionでエラーになってしまう
(他の記事では大抵そうやってる)

回答: 不要
ver 2.0.5を使用している状態で

import VeeValidate from 'vee-validate'
Vue.use(VeeValidate)
<input
  name="birthday"
  type="date"
  v-validate="'date_format:YYYY-MM-DD'"
>

上記で日付フォーマットのvalidationが動作する。

 むりくり

日付の前後比較をバリデートしたい
例: 開始日が終了日よりも後ではいけない的な・・

下記ののように beforeを使うことで対応できたが、
endDateが日本語化されない

<div class="field">
  <div class="control">
    <input
      name="startDate"
      v-model="startDate"
      data-vv-as="開始日"
      v-validate="'before:endDate|date_format:YYYY-MM-DD'"
      type="date"
      placeholder="開始日">
    >
    ー
    <input
      name="endDate"
      v-model="endDate"
      data-vv-as="終了日"
      v-validate="'date_format:YYYY-MM-DD'"
      type="date"
      placeholder="終了日">
    >
  </div>
  <p v-show="errors.has('startDate')" class="help is-danger">{{ errors.first('startDate') }}</p>
  <p v-show="errors.has('endDate')" class="help is-danger">{{ errors.first('endDate') }}</p>
</div>


どうしようもないのでfiltersに置換するメソッドを追加

  filters: {
    localizeEndDate (message) {
      if (typeof (message) == "string" || message instanceof String) {
        return message.replace('contractStartDate', '契約終了日')
      }
    }
  }

メッセージ出力のところを下記のようにする
{{ errors.first('endDate') | localizeEndDate }}

ちなみに、beforeバリデーションの対になるafterバリデーションもある。
会員管理とかで退会日はnull可で入会日は必ず存在するような場合に向いてる。

調査中