v-если не работает для проверки формы и отображения ошибок - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь проверить простую форму, которая содержит два поля:

  • Поле выбора
  • Поле файла

Если одно из поля не заполнены, 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>

Ответы [ 3 ]

0 голосов
/ 25 февраля 2020

Причина может заключаться в том, что способ переназначения объекта не является реактивным, что не вызывает 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' }
0 голосов
/ 25 февраля 2020

Способ обработки моих ошибок с помощью VueJS заключается в использовании списков и их атрибута length.

В моих данных есть объект errors, который выглядит следующим образом:

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

Затем, когда я отправлю форму, я:

  • Очистим все списки от ошибок (ie очистим предыдущие ошибки)
  • .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>

Надеюсь, это поможет

0 голосов
/ 25 февраля 2020

Очевидно, мне пришлось использовать v-show вместо v-if, потому что v-if будет 'ленивым' и не будет отображать мой error-div при заполнении ошибок var.

Это работает сейчас, но не уверен на 100%, если это лучший способ, как я нашел другой учебник, где v-if используется для проверки формы. (https://medium.com/@mscherrenberg / laravel -5 -6- vue - js -простые формы-представление-используя-компоненту-92b6d5fd4434 )

...