【问题标题】:Vuelidate custom validation shows error on every element in $eachVuelidate 自定义验证在 $each 中的每个元素上显示错误
【发布时间】:2020-03-03 08:58:00
【问题描述】:

我有一个formData 对象,其结构如下:

{
  name: '',
  defaultPort: 1000,
  protocolPorts: [{
    manual_ports: []
  }]
}

manual_ports 是一个可以动态添加的字符串数组。对于每个这样的端口,我想用 Vuelidate 进行一些验证。

formData: {
    name: { required, maxLength: maxLength(64) },
    protocolPorts: {
      $each: {
        manual_ports: {
          $each: {
            required,
            numeric,
            maxLength: maxLength(5),
            between: between(1, (Math.pow(2, 16) - 1)),
            cantBeginWithZero,
            cantBeDuplicate
          }
        }
      }
    }
  }

最后一个验证是cantBeDuplicate - 我想检查当前编辑的端口是否与任何其他端口或defaultPort 重复。问题是它目前可以工作,但是它在每个端口文本字段下都显示错误,而不仅仅是在当前正在编辑的那个之后。有什么方法可以实现吗?

到目前为止,我已经尝试过:

function cantBeDuplicate (val) {

  if (val) {
    let ports = [...this.currentProtocol.manual_ports];
    ports.splice(this.currentPortIndex, 1);
    return this.currentProtocol.manual_ports.length > 1 ?
      !ports.includes(val) :
      +this.currentProtocol.manual_ports[this.currentPortIndex] === +this.currentProtocol['default_port'] || true;
  } else {
    return true;
  }
}

...还有这个:

return val ?
  (!_.initial(this.currentProtocol.manual_ports).includes(val) && +this.currentProtocol['default_port'] !== +val) : true;

这就是我的文本字段的定义方式(它们在 v-for 循环中):

<v-text-field
  v-model="protocol['manual_ports'][index]"
  :error-messages="portsErrors"
  label="Port"
  height="30"
  single-line
  flat
  dense
  required
  @click="setCurrents(protocol, index)"
  @blur="$v.formData.protocolPorts.$each[pi]['manual_ports'].$each[index].$touch()"
  @input="$v.formData.protocolPorts.$each[pi]['manual_ports'].$each[index].$touch()" />

这是portsError 计算属性:

portsErrors() {
    const errors = [];
    if ( this.currentProtocol) {
      const protocolIndex = findIndex(this.formData.protocolPorts, p => p.id === this.currentProtocol.id)

      if (!this.$v.formData.protocolPorts.$each[protocolIndex].manual_ports.$each[this.currentPortIndex].$dirty) {
        return errors;
      }
      !this.$v.formData.protocolPorts.$each[protocolIndex].manual_ports.$each[this.currentPortIndex].numeric && errors.push('Digits only')
      !this.$v.formData.protocolPorts.$each[protocolIndex].manual_ports.$each[this.currentPortIndex].maxLength && errors.push('Max 5 digits')
      !this.$v.formData.protocolPorts.$each[protocolIndex].manual_ports.$each[this.currentPortIndex].between && errors.push('Range: 1 - 65535')
      !this.$v.formData.protocolPorts.$each[protocolIndex].manual_ports.$each[this.currentPortIndex].cantBeginWithZero && errors.push('No leading 0')
      !this.$v.formData.protocolPorts.$each[protocolIndex].manual_ports.$each[this.currentPortIndex].cantBeDuplicate && errors.push('No duplicates')
      !this.$v.formData.protocolPorts.$each[protocolIndex].manual_ports.$each[this.currentPortIndex].required && errors.push('Required')
    }
    return errors
  },

是否可以只在当前编辑的端口下方显示错误信息?

【问题讨论】:

    标签: vue.js vuetify.js vuelidate


    【解决方案1】:

    好的,我找到了解决方案: 这是它发生的关键原因,我引用自己的话:

    它们在一个 v-for 循环中

    由于 v-text-field 在 v-for 循环中 - 当然,此循环中的每个元素都将具有相同的验证。解决方案是将文本字段包装在包装器组件中,传递必要的 props 并仅在组件内部对 prop 进行验证,同时在父组件中发出结果并进行处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多