8
7

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 5 years have passed since last update.

vee-validate と bootstrap-vue を連携させてお手軽フォームバリデーションを実現する

Posted at

https://github.com/mashiro/vee-bootstrap-example
Edit vee-bootstrap-example

お手軽に使えて非常に便利な vee-validate の errors を指定する部分をコンポーネントに切り出してさらに簡単に扱えるようにする。
bootstrap-vue では form-validation の例として vuelidate があげられているが、 vee-validate のほうが使い方がシンプルで v-if で非表示にした要素は validation の対象にならないなど極めて直感的に扱えるのでこちらが個人的におすすめ。

MyFormGroup.vue
<template>
  <b-form-group
    v-bind="$attrs"
    v-on="$listeners"
    :invalidFeedback="invalidFeedback"
    :state="state"
  >
    <slot
      :$name="name"
      :$state="state"
    />
  </b-form-group>
</template>

<script>
export default {
  inject: ["$validator"],
  props: {
    name: {
      type: String,
      required: true
    }
  },
  computed: {
    errors() {
      return this.$validator.errors;
    },
    state() {
      return this.errors.has(this.name) ? false : null;
    },
    invalidFeedback() {
      return this.errors.first(this.name);
    }
  }
};
</script>

b-form-group には bootstrap の feedback を扱うための便利なプロパティがあるのでそこに vee-validate から取得した情報を設定してあげるような wrapper を用意してあげればいい。

$validator を inject することにより親コンポーネントの mixin で provide された validator インスタンスを得ることができるのでそこから errors を取得することによりバリデーションの状態を取得することができる。

errors からあるグループの状態を得るために名前が必要なため form-group に name プロパティを持たせている。
また、この name プロパティは子コンポーネントの from-input などでも同じものを用いるため scope で再利用できるようにしている。
state も入力コンポーネントの状態を変更するために必要なのでこちらも scope に渡す。

実際に使うとこの様になる。

Example.vue
<my-form-group name="email" label="Email">
  <template slot-scope="scope">
    <b-form-input
      type="email"
      :name="scope.$name"
      :state="scope.$state"
      v-model="form.email"
      v-validate="{ required: true, email: true }"
    />
  </template>
</my-form-group>

一般的な Vue のアプローチから外れず極めてシンプルに実現できたのではないでしょうか。

vee-validate の若干よろしくない点としては inject すると errors, fields というあきらかにぶつかりそうなフィールド名を使用するので設定でプリフィクスをつけるなどして変更しておくといい。
自動インジェクションも無駄な負荷につながるので無効でいいでしょう。

app.js
Vue.use(VeeValidate, {
  inject: false,
  errorBagName: "vvErrors",
  fieldsBagName: "vvFields"
});
8
7
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
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?