Vuelidate 通用验证逻辑

Vuelidate common validation logic

我目前正在学习前端 javascript 开发,目前正在使用 VueJS、Vuetify 和 Vuelidate 做一个个人项目。

我有一个简单的问题。

我有两个文本字段,如下所示。

  <v-layout wrap>
    <v-flex>
      <v-text-field
        label="First Name"
        maxlength="20"
        v-model.trim="firstName"
        :error-messages="firstNameErrors"
        @input="$v.firstName.$touch()"
        @blur="$v.firstName.$touch()"
      ></v-text-field>
    </v-flex>
    <v-flex>
      <v-text-field
        label="Last Name"
        v-model.trim="lastName"
        maxlength="20"
        :error-messages="lastNameErrors"
        @input="$v.lastName.$touch()"
        @blur="$v.lastName.$touch()"
      ></v-text-field>
    </v-flex>
  </v-layout>

我在计算钩子中写了一个 vuelidate,如下所示。

  computed: {
    firstNameErrors () {
      const errors = []
      if (!this.$v.firstName.$dirty) return errors
      !this.$v.firstName.required && errors.push('First Name is required')
      return errors
    },
    lastNameErrors () {
      const errors = []
      if (!this.$v.lastName.$dirty) return errors
      !this.$v.lastName.required && errors.push('Last Name is required')
      return errors
    }

代码工作正常并且做了应该做的事情,生成验证错误,"required" 在我的例子中。

我的问题是,我想在一个名为 "requiredErrors" 的函数下包含验证错误函数 "firstNameErrors" 和 "lastNameErrors",而不是有两个单独的函数。

码笔:https://codepen.io/pen/jebLgM

非常感谢任何帮助。

谢谢。

我不符合你的逻辑,但从字面上理解你的请求可能是这样的:

 <v-layout wrap>
    <v-flex>
      <v-text-field
        label="First Name"
        maxlength="20"
        v-model.trim="firstName"
        :error-messages="requiredErrors"
        @input="$v.firstName.$touch()"
        @blur="$v.firstName.$touch()"
      ></v-text-field>
    </v-flex>
    <v-flex>
      <v-text-field
        label="Last Name"
        v-model.trim="lastName"
        maxlength="20"
        :error-messages="requiredErrors"
        @input="$v.lastName.$touch()"
        @blur="$v.lastName.$touch()"
      ></v-text-field>
    </v-flex>
  </v-layout>

  computed: {
    requiredErrors () {
      const errors = []
      this.$v.firstName.$dirty 
        && !this.$v.firstName.required 
        && errors.push('First Name is required')
      this.$v.lastName.$dirty
        && !this.$v.lastName.required 
        && errors.push('Last Name is required')
      return errors
    }

更新

是的,这就是为什么我说我不符合你的逻辑(两个输入的消息相同)。您可能可以通过 bind-ing 使用不同的第一个参数多次调用您的函数来实现您想要的,但该函数不再是您组件的方法(因为它们已经被 Vue 绑定)。

也许是这样的:

<v-text-field
    label="First Name"
    maxlength="20"
    v-model.trim="firstName"
    :rules="requiredErrorsFirstName"
    @input="$v.firstName.$touch()"
    @blur="$v.firstName.$touch()"
  ></v-text-field>

<v-text-field
    label="Last Name"
    v-model.trim="lastName"
    maxlength="20"
    :rules="requiredErrorsLastName"
    @input="$v.lastName.$touch()"
    @blur="$v.lastName.$touch()"
  ></v-text-field>

computed:
{
  requiredErrorsFirstName ()
  {
    return [requiredErrors.bind(this,'firstName')];
  },
  requiredErrorsLastName ()
  {
    return [requiredErrors.bind(this,'lastName')];
  }
}

function requiredErrors(fieldName, fieldValue)
{
  switch(fieldName)
  {
    case 'firstName':
      return this.$v[fieldName].$dirty 
            && !this.$v[fieldName].required 
            ? 'First Name is required' : true;
    case 'lastName':
      return this.$v[fieldName].$dirty 
            && !this.$v[fieldName].required 
            ? 'Last Name is required' : true;   
  }
}

我个人认为这很丑陋,我更愿意为每个字段单独计算 属性 或方法。