【问题标题】:v-if not working for form validation and displaying errorsv-if 不适用于表单验证和显示错误
【发布时间】:2020-06-08 09:58:58
【问题描述】:

我正在尝试验证一个包含两个字段的简单表单:

  • 一个选择框
  • 文件字段

如果其中一个字段未填写,则应在相应输入字段旁边呈现一个 div(包含错误标签)。

问题:将数据推送到错误对象时(如果表单无效),我的“错误 div”未呈现。 请注意我的 console.log 语句,它告诉我我的错误对象有一个键 'file' 和一个键 'selectedSupplier'。

旁注:我正在关注这个例子:https://vuejs.org/v2/cookbook/form-validation.html 不同之处在于,我想在相应字段旁边显示错误标签,并且我在我的错误对象中设置错误,而不是简单的数组。那么我做错了什么?

谢谢。

这是我的 Main.vue 文件:

<template>
    <div>
        <form @submit="upload">
            <div class="mb-8">
                <h1 class="mb-3 text-90 font-normal text-2xl">Import Order Csv</h1>
                <div class="card">
                    <div class="flex border-b border-40">
                        <div class="w-1/5 px-8 py-6">
                            <label for="supplier_id" class="inline-block text-80 pt-2 leading-tight">Supplier</label>
                        </div>

                        <div class="py-6 px-8 w-1/2">
                            <select v-model="selectedSupplier" id="supplier_id" name="supplier_id" ref="supplier_id" class="w-full form-control form-input form-input-bordered">
                                <option v-for="supplier in suppliers" v-bind:value="supplier.id">{{ supplier.name }}</option>
                            </select>

                            <div v-if="errors.hasOwnProperty('selectedSupplier')" class="help-text error-text mt-2 text-danger">
                                Required.
                            </div>
                        </div>
                    </div>

                    <div class="flex border-b border-40">
                        <div class="w-1/5 px-8 py-6">
                            <label for="csv_file" class="inline-block text-80 pt-2 leading-tight">File</label>
                        </div>

                        <div class="py-6 px-8 w-1/2">
                            <input id="csv_file" type="file" name="file" ref="file" @change="handleFile">

                            <div v-if="errors.hasOwnProperty('file')" class="help-text error-text mt-2 text-danger">
                                Required.
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="flex items-center">
                <button type="submit" class="btn btn-default btn-primary inline-flex items-center relative">Import</button>
            </div>
        </form>
    </div>
</template>

<script>
    export default {
        mounted() {
            this.listSuppliers();
        },
        data() {
            return {
            errors: [],
            file: '',
            suppliers: [],
        };
    },
    methods: {
        checkForm() {
            if (!this.selectedSupplier) {
                this.errors.selectedSupplier = 'Supplier required';
            }

            if (!this.file) {
                this.errors.file = 'File required';
            }
        },
        listSuppliers() {
            const self = this;

            Nova.request()
                .get('/tool/import-order-csv/suppliers')
                .then(function (response) {
                    self.suppliers = response.data.data;
                })
                .catch(function (e) {
                    self.$toasted.show(e, {type: "error"});
                });
        },
        handleFile: function (event) {
            this.file = this.$refs.file.files[0];
        },
        upload: function (event) {
            this.checkForm();

            if (this.errors.hasOwnProperty('selectedSupplier') || this.errors.hasOwnProperty('file')) {
                console.log(this.errors); // this actually shows both errors!
                event.preventDefault();
            }

            const formData = new FormData();
            formData.append('file', this.file);

            formData.append('supplier_id', this.$refs.supplier_id.value);

            const self = this;

            Nova.request()
                .post('/tool/import-order-csv/upload',
                    formData,
                    {
                        headers: {
                            'Content-Type': 'multipart/form-data'
                        }
                    }
                ).then(function (response) {
                    self.$toasted.show(response.data.message, {type: "success"});
                })
                .catch(function (e) {
                    self.$toasted.show(e.response.data.message, {type: "error"});
                });
            }
        }
    }
</script>

【问题讨论】:

  • 您使用错误作为对象,但在 data() 中您传递一个空数组作为初始值
  • 感谢您的反馈。不过,这还没有解决:(

标签: vue.js vue-component


【解决方案1】:

显然我不得不使用 v-show 而不是 v-if,因为 v-if 将是“惰性”的,并且在填充错误 var 时不会呈现我的错误 div。

它现在可以工作,但不能 100% 确定这是否是最好的方法,因为我发现了另一个使用 v-if 进行表单验证的教程。(https://medium.com/@mscherrenberg/laravel-5-6-vue-js-simple-form-submission-using-components-92b6d5fd4434)

【讨论】:

    【解决方案2】:

    原因可能是因为你重新分配对象的方式不是响应式的,这不会触发 v-if 重新计算

    this.errors.selectedSupplier = 'Supplier required';
    this.errors.file = 'File required';
    

    如果你仍然想使用 v-if ,尝试改变这种方法

    this.errors = {...this.errors, selectedSupplier: 'Supplier required' }
    
    this.errors = {...this.errors, file: 'File required' }
    

    【讨论】:

      【解决方案3】:

      我使用 VueJS 处理错误的方式是通过列表及其 length 属性。

      我的数据中有一个errors 对象,如下所示:

      errors: {
        field1: [],
        field2: [],
      }
      

      然后,当我提交表单时,我会:

      • 清空所有错误列表(即清除以前的错误)
      • .push() 正确列表中的新错误(.push() 使 Vue 反应)

      最后,在我的表单中,我各自的错误 div 是根据列表的长度显示的:

      <div class="error" v-if="errors.field1.length > 0">
          use a v-for to display all the errors from the list
      </div>
      

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        我遇到了同样的错误,这就是我解决问题的方法,

        <div v-if="errors.field1.length > 0 ? true : false"> // true or false 
        

        如果你像这样修复代码,它将起作用

        【讨论】:

        • 选择您的代码并按 Ctrl + K 格式化您的代码
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-19
        • 1970-01-01
        • 1970-01-01
        • 2013-05-31
        相关资源
        最近更新 更多