使用Vee-Validate验证提交时的子输入组件

时间:2016-12-07 16:46:07

标签: vue.js

我目前正在尝试使用多个“输入字段”组件创建一个注册表单,一旦按下提交,这些组件都需要验证。当文本内部发生变化时,它们都会自行验证,但我发现很难对所有输入字段进行全局调用以验证所有内容。我想要实现的目标如下:http://vee-validate.logaretm.com/examples#validate-form但validateAll()方法没有附加字段。

我尝试使用email&amp ;;填充validateAll() confirm_email给了我想要的结果,但错误消息不会显示在字段旁边。

非常感谢任何帮助!

ValidatedInputField.vue:

<template>
   <div class="form-control" v-bind:class="{ errorPrompt : errors.has(name) }">
      <label v-bind:for="name">* {{as}}</label>
      <input ref="input" v-bind:value="_value" @input="updateValue($event.target.value)" v-validate v-bind:data-vv-rules="rules" v-bind:name="name" />
      <span v-bind:v-show="'errors.has(' + name +')'">{{ errors.first(name) }}</span>
   </div>
</template>

<script>
module.exports = {
  props: ['name', 'rules', 'as', 'value'],
  methods: {
  updateValue(value) {
     this._value = this.value;
     this.$emit('input', value);
  }
  },
  computed: {
     _value() { return this.value; }
  }
};
</script>

Register.vue:

<template>
  <div class="container">
    <Card blueHeader="true" title="Register">
      <ValidatedInputField v-model="email" name="email" rules="required|email" as="Email" />
      <ValidatedInputField v-model="confirm_email" name="confirm_email" rules="required|email" as="Confirm Email" />
      <ValidatedInputField name="company" rules="required" as="Company" />
      <InputField name="company_website" as="Company Website" />
      <ValidatedInputField name="first_name" rules="required" as="First Name" />
      <ValidatedInputField name="last_name" rules="required" as="Last Name" />
      <ValidatedInputField name="address_1" rules="required" as="Address 1" />
      <InputField name="address_2" as="Address 2" />
      <ValidatedInputField name="city" rules="required" as="City" />
      <ValidatedInputField name="zip" rules="required" as="Zip/Postal Code" />
    </Card>

    <Card blueHeader="true" title="Terms & Conditions">
      <button v-on:click="submitForm()">Submit</button>
    </Card>
  </div>
</template>

<script>
import ValidatedInputField from './components/ValidatedInputField';
import InputField from './components/InputField';

module.exports = {
  methods: {
    submitForm() {
      this.$validator.validateAll();
    }
  },
  data() {
    return {
      email: '',
      confirm_email: ''
    };
  },
  components: {
    ValidatedInputField,
    InputField
  }
};
</script>

6 个答案:

答案 0 :(得分:5)

我有类似的设置,我尝试了事件的总线解决方案,没有让它工作。然而,我使用了v-validate规范中定义的Provider / Injector模式。

所以在最顶级的父级中,添加这行代码(介意它是TYPESCRIPT!)

 @Provide('validator') $validator = this.$validator;

在每个孩子/孙子中添加以下代码:

@Inject('validator') $validator: any;

现在您可以在父级中执行此操作,我将使用验证器注入器收集所有组件的所有错误。 (见规格:https://baianat.github.io/vee-validate/api/errorbag.html#api

 if (this.$validator.errors.any()) {
      // Prevent the form from submitting
      e.preventDefault();
    }

我在帖子里有一个类似的答案; vee-validate error object - _vm.errors is undefined

grtz

答案 1 :(得分:4)

我不确定我是否理解正确。但是要全局调用,您必须在单击按钮时发出事件并指示每个模板对该事件执行操作。每个模板的操作应该是'this。$ validator.validateAll()',因为'this'将引用该特定模板。

您可以通过创建命名实例(“总线”)来实现。在创建实例之前创建它。

var bus = new Vue({});

使用它从模板中发出:

bus.$emit('validate_all');

并抓住模板:

created: function() {
   var vm = this;
   bus.$on('validate_all', function() {
      vm.$validator.validateAll()
   });
}

现在应该验证所有字段并显示所有错误消息。 祝你好运!

答案 2 :(得分:3)

我正在使用不同的验证器库。我还没有听说过vee-validate,但它看起来很整洁,我可能会切换,因为它支持Vue 2.0,而vue-validator现在不支持。它们在概念上看起来非常相似。

假设您没有使用Vuex并且这是一个小应用程序,您可以使用计算属性来获取每个子项的验证状态:

父:

isValid: function () { 
    for (var i = 0; i < this.$children.length; i++) {
      if (this.$children[i].hasOwnProperty('isValid') && !this.$children[i].isValid) {
        return false
      }
    }
    return true
  }

子:

  isValid: function () {
    return this.$vueValidator.valid
  }

如果您有孩子,您不想要验证,请不要给它isValid计算财产。

当孩子从无效状态更改状态时,您还可以$emit来自孩子的事件 - &gt;有效或有效 - &gt;无效告诉父母。

答案 3 :(得分:3)

对于普通的Vuejs,我使用:

inject: ['$validator'],

在孩子中,

和:

provide() {
   return {
     $validator: this.$validator,
   };
},

在父母中。

答案 4 :(得分:2)

就我而言,我要做的是禁用vee-validate注入:

Vue.use(VeeValidate, { inject: false });
  

这将使插件停止为每个组件实例实例化新的验证程序范围,   排除根实例。

在父组件中,我得到一个新的验证器实例,该实例将与所需的子代共享:

export default {
  $_veeValidate: {
      validator: 'new' // Determines how the component get its validator instance
                       // 'new' means it will always instantiate its own validator instance
  },
  ......

在子组件中,我注入该父组件的验证器实例:

export default {
    // This will make the component inherit it's parent's validator scope,
    // thus sharing all errors and validation state. Meaning it has access
    // to the same errors and fields computed properties as well.
    inject: ['$validator'],
    ...........

资源:https://baianat.github.io/vee-validate/concepts/components.html

答案 5 :(得分:0)

在提交表单之前,我不得不使用诺言来检查验证。

下面来自@ChalkyJoe原始问题的代码

module.exports = {
  methods: {
    submitForm() {
      //this.$validator.validateAll();
      this.$validator.validateAll().then((result)=>{
          if(!result){
            error();
          }
          submit();
      })
    }
  },
  data() {
    return {
      email: '',
      confirm_email: ''
    };
  },