【问题标题】:Validate with Vuelidate on dynamic fields在动态字段上使用 Vuelidate 进行验证
【发布时间】:2020-04-29 16:43:52
【问题描述】:

我有一个在点击事件上动态添加字段的表单。当我更改或模糊它后,当字段值小于 9 位时,我试图显示一个 minlength 验证错误(这并不重要)。我的问题是,因为这些字段是动态创建的,并且本质上是相同的 v-model,所以它将规则应用于所有字段。我怎样才能使这项工作只影响用户所在的那个?屏幕会加载其中的 10 个,然后他们可以添加更多。因此,当他们填写最初的 10 个字段时,我不希望在以下所有字段的第 5 个字段之后弹出验证,因为第 5 个字段失败了。

这是我的代码的简化版本

<template>
    <div>
        <div>
            <button @click="onAddBarcodes">Add More</button>
        </div>
        <div v-for="(barcode, index) in barcodes" :key="index">
            <div>
                <div>
                    <label>Starting Roll #:</label>
                    <input
                        name="startbarcoderoll"
                        maxlength="9"
                        v-model.trim="$v.barcode.barcodeStart.$model"
                        :id="barcode.id"
                        ref="bcentry"
                    />
                    <!-- max length message -->
                    <div v-if="!$v.barcode.barcodeStart.minLength">
                        <span
                            v-if="!$v.barcode.barcodeStart.minLength"
                        >App Barcode must be exactly {{$v.barcode.barcodeStart.$params.minLength.min}} characters.</span>
                    </div>
                </div>
                <button @click="onDeleteBarcodes(barcode.id)">Remove</button>
            </div>
        </div>
    </div>
</template>

<script>
const { minLength } = require("vuelidate/lib/validators");

export default {
    data() {
        return {
            barcodes: [],
            barcode: {
                barcodeStart: ""
            }
        };
    },
    validations: {
        barcode: {
            barcodeStart: {
                minLength: minLength(9)
            }
        }
    },
    methods: {
        scanBarcodeNumber(value) {
            this.barcode.barcodeStart = value;
            this.$v.barcode.barcodeStart.$touch();
        },

        onAddBarcodes() {
            const newBarcode = {
                id: Math.random() * Math.random() * 1000,
                barcodeStart: ""
            };
            this.barcodes.push(newBarcode);
        },
        onDeleteBarcodes(id) {
            this.barcodes = this.barcodes.filter(barcode => barcode.id !== id);
        }
    }
};
</script>

让我看看发生了什么

编辑:Vuelidate 在全局 Vue 实例中安装和实例化,因此我可以在多个地方使用它。这就是为什么您在此特定代码中看不到它的原因

【问题讨论】:

    标签: javascript vue.js vuelidate


    【解决方案1】:

    使用validations 函数使用动态验证,并为每个barcode 添加一个validation

    对每个字段使用$v[`barcode-${index}`] 而不是$v.barcode

    <template>
        <div>
            <div>
                <button @click="onAddBarcodes">Add More</button>
            </div>
            <div v-for="(barcode, index) in barcodes" :key="index">
                <div>
                    <div>
                        <label>Starting Roll #:</label>
                        <input
                            name="startbarcoderoll"
                            maxlength="9"
                            v-model.trim="$v[`barcode-${index}`].barcodeStart.$model"
                            :id="barcode.id"
                            ref="bcentry"
                        />
                        <!-- max length message -->
                        <div v-if="!$v[`barcode-${index}`].barcodeStart.minLength">
                            <span
                                v-if="!$v[`barcode-${index}`].barcodeStart.minLength"
                            >App Barcode must be exactly {{$v[`barcode-${index}`].barcodeStart.$params.minLength.min}} characters.</span>
                        </div>
                    </div>
                    <button @click="onDeleteBarcodes(barcode.id)">Remove</button>
                </div>
            </div>
        </div>
    </template>
    

    在您的 js 部分中使用 function 定义 validations 并为搜索字段定义条形码:

    export default {
      validations() {
        const rules = {};
        this.barcodes.forEach((item, index) => {
          rules[`barcode-${index}`] = {
            barcodeStart: {
              minLength: minLength(9),
            },
          };
        });
        return rules;
      },
    };
    

    我不知道这是否有效,但它必须按您的意愿工作。

    【讨论】:

    • 所以,当我模糊不清时,它正在清空我的 v-model。或者我应该说,它没有约束力。换句话说,我可以在字段中输入,当我模糊时,它会删除我输入的内容
    【解决方案2】:

    您可能应该使用 Vuelidate $each

    在此处查看文档:
    https://vuelidate.js.org/#sub-collections-validation

    这里也有人发了一篇文章:
    https://jasonwatmore.com/post/2020/09/30/vuejs-vuelidate-dynamic-form-example

    【讨论】:

      猜你喜欢
      • 2018-04-25
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2020-01-15
      相关资源
      最近更新 更多