如果另一个相关字段发生更改,则强制进行新的验证

时间:2019-07-09 13:18:10

标签: vue.js vuetify.js

我想验证两个相互关联的文本字段。第一个必须小于第二个(例如,最小/最大,开始日期/结束日期)。

所以对于编码部分,我创建了这个

HTML:

Add to the list of variables

Name - "someArray[0]"

Variable - "someText"

JS:

<div id="app">
  <v-app id="inspire">
          <v-text-field
              v-model="values[0]"
              :rules="firstValidation"
            ></v-text-field>

            <v-text-field
              v-model="values[1]"
              :rules="secondValidation"
            ></v-text-field>
  </v-app>
</div>

我还将在此处提供一个代码段

https://codepen.io/anon/pen/NZoaew?editors=1010

当我更改一个字段的值时,另一个字段将不会重新验证。重现步骤:

  • 将第一个字段的值更改为12

第二个字段的值为2,所以您会得到一个错误

  • 将第二个字段的值更改为22

现在该表单有效,但是第一个字段仍会引发错误,因为它没有重新验证。

  • 从第一个字段中删除一个字符

现在此字段重新生效,您可以提交它。是否有一种机制可以使更改后的其他字段重新生效,反之亦然?

我认为可能的解决方案是侦听某个字段的new Vue({ el: '#app', data () { return { values: [1, 2] } }, computed: { firstValidation: function () { return [value => parseFloat(value) < this.values[1] || "Must be less than second value"] }, secondValidation: function () { return [value => parseFloat(value) > this.values[0] || "Must be greater than first value"] } } }) 事件,但是您将如何迫使另一个字段重新验证呢?

2 个答案:

答案 0 :(得分:2)

这将同时验证它们,但仅当用户在该字段中键入内容时,才会在该字段中显示错误:

new Vue({
  el: '#app',
  data () {
    return {
      values: [1, 2],
      firstValidation: [true],
      secondValidation: [true]
    }
  },
  methods: {
    validate: function (index) {
      const valid = (this.values[0] - this.values[1]) < 0
      if (valid) {
        this.firstValidation = [true];
        this.secondValidation = [true];
        return;
      }
      if (index > 0)
        this.secondValidation = ["Must be greater than first value"];
      else
        this.firstValidation = ["Must be less than second value"];
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@1.5.16/dist/vuetify.min.js"></script>

<div id="app">
  <v-app id="inspire">
          <v-text-field
              v-model="values[0]"
              @input="validate(0)"
              :rules="firstValidation"
            ></v-text-field>
            
            <v-text-field
              v-model="values[1]"
              @input="validate(1)"
              :rules="secondValidation"
            ></v-text-field>
  </v-app>
</div>

(我不确定为什么不渲染样式,但是它使用与Codepen相同的脚本)

答案 1 :(得分:1)

为什么您的数据模型是数组?请注意这一点。从docs

  

由于JavaScript的限制,Vue无法检测以下内容   更改为数组:

     

直接用索引设置项目时,例如   vm.items[indexOfItem] = newValue

即调用values[1] = parseFloat($event)时,它是无反应的。如果可能,我会避免这种情况,否则请使用$set。然后,要在另一个字段发生更改时强制验证该字段,您将必须注意更改,然后手动调用验证。

模板

<div id="app">
  <v-form ref="form"> <!-- Need a reference to the form to validate -->
    <v-app id="inspire">
            <v-text-field
                :value="values[0]"
                :rules="firstValidation"
                @input="$set(values, 0, parseFloat($event))"
              ></v-text-field>

              <v-text-field
                :value="values[1]"
                :rules="secondValidation"
                @input="$set(values, 1, parseFloat($event))"
              ></v-text-field>

            <v-btn @click="submit">Submit</v-btn>
    </v-app>
  </form>
</div>

代码

将此添加到您的组件

methods: {
    submit: function(){
      console.log(this.values);
    },
    validate: function() {
      // manually call validation
      this.$refs.form.validate();
    }
  },
  watch: {
    // watch for change and then validate
    values: 'validate'
  }

查看更新的工作codepen