如何在 v-for 中使用 v-form 并对特定表单执行验证?

How to use v-form inside a v-for and perform validation for a specific form?

我有一个对象数组,我应该遍历这些对象并为每个对象的属性显示一个表单。保存按钮不在 for 循环中。在附带的沙箱中,第二个对象不包含姓氏。那么,如何仅针对第二种形式在单击“保存”按钮时执行验证?有没有办法一次验证所有表格?请参考沙盒以更好地理解。

https://codesandbox.io/s/jolly-kepler-m260fh?file=/src/components/Playground.vue

因为提交按钮在表单之外。我们可以通过迭代名称数组来对提交事件执行验证,并检查是否有任何值是空的,然后为每个对象分配一个有效的标志值(true/false)。

演示 :

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data: () => ({
    names: [
      {
        firstName: "john",
        lastName: "doe",
        age: 40,
        valid: false
      },
      {
        firstName: "jack",
        lastName: "",
        age: 30,
        valid: false
      },
    ],
    requiredRule: [v => !!v || 'Value is required']
  }),
  methods: {
    submitForm() {
      this.names.forEach((obj, index) => {
        if (!obj.lastName) {
            obj.valid = false;
          console.log(
            `${index + 1}nd form is not valid as LastName is not available`
          );
        } else {
            obj.valid = true;
        }
      });
      
      // Now you can filter out the valid form objects based on the `valid=true`
    }
  }
})
<script src="https://unpkg.com/vue@2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify@2.6.6/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify@2.6.6/dist/vuetify.min.css"/>
<div id="app">
  <v-app id="inspire">
    <v-container class="pl-10">
    <v-row v-for="(name, index) in names" :key="index">
      <v-form v-model="name.valid">
        <v-col cols="12">
          <v-text-field v-model="name.firstName" outlined dense solo required :rules="requiredRule" />
        </v-col>
        <v-col cols="12">
          <v-text-field v-model="name.lastName" outlined dense solo required :rules="requiredRule" />
        </v-col>
        <v-col cols="12">
          <v-text-field v-model="name.age" outlined dense solo required :rules="requiredRule" />
        </v-col>
      </v-form>
    </v-row>
    <v-btn type="submit" @click="submitForm"> Submit </v-btn>
      </v-container>
  </v-app>
</div>

检查我制作的这个codesandbox:https://codesandbox.io/s/stack-72356987-form-validation-example-4yv87x?file=/src/components/Playground.vue

如果将 v-form 移到 for 循环之外,您可以一次验证所有 v-text-field。您需要做的就是给表单一个 ref 值和一个 v-model 以使用内置的 vuetify 验证方法。

<template>
  <v-container class="pl-10">
    <v-form ref="formNames" v-model="validForm" lazy-validation>
      <v-row v-for="(name, index) in names" :key="index">
        <v-col cols="12">
          <v-text-field
            v-model="name.firstName"
            outlined
            dense
            solo
            :rules="rulesRequired"
          />
        </v-col>
        ...
      </v-row>
    </v-form>
    <v-btn type="submit" @click="submitForm" :disabled="!validForm">
      Submit
    </v-btn>
  </v-container>
</template>

然后在提交按钮中你需要做的就是通过$refs对象调用表单的validate()方法。如果表单中的任何元素未通过验证规则,您还可以禁用提交按钮,使用表单的 v-model 禁用提交按钮。

<script>
export default {
  name: "playground",
  data: () => ({
    validForm: true,
    names: [
      {
        firstName: "john",
        lastName: "doe",
        age: 40,
      },
      {
        firstName: "jack",
        lastName: "",
        age: 30,
      },
    ],
    rulesRequired: [(v) => !!v || "Required"],
  }),
  methods: {
    submitForm() {
      if (this.$refs.formNames.validate()) {
        // Form pass validation
      }
    },
  },
};
</script>