2

我遇到了我遇到过的最奇怪的错误。我在我的 Vue 项目中使用 Axios 和 Vee-Validate 并且从我的 api 我得到一个错误。所以有了 axios 我有一个问题。

例子:

this.$http.post('v1/auth/register', {
                first_name: this.first_name,
                last_name: this.last_name,
                email: this.email,
                phone: this.phone,
                password:this.password
            }).then((response) => {
                this.registration_card = 2;
            }).catch((error) => {

                if(error.data.error.message === "email_already_exists") {
                    let input = this.$refs['email'].$children[0];
                    input.errors.add({ field: 'email', msg: 'email already is use'});
                    this.loading = false;

                    console.log(input.errors);
                    console.log(this.loading);
                }

            });

现在奇怪的部分来了。使用此代码:

let input = this.$refs['email'].$children[0];
    input.errors.add({ field: 'email', msg: 'email already is use'});

this.loading = false;

input.errors 仍然为空,不会显示错误。但是当我这样做时:

let input = this.$refs['email'].$children[0];
    input.errors.add({ field: 'email', msg: 'email already is use'});

 // this.loading = false;

所以 this.loading 不会被设置,然后错误将被设置并显示在我的视图中。

但我希望 this.loading 仍然是错误的,因为我希望不显示我的加载图标。任何人对此都有解释。

编辑:更多代码

methods: {
    register: function () {
        let anyError = false;
        this.$validate(this, ['first_name', 'last_name', 'phone', 'email', 'password'], function (value, last_item) {

            this.loading = true;

            if (value === false) {
                anyError = true;
            }

            if (anyError || !last_item) {
                return;
            }

            this.$http.post('v1/auth/register', {
                first_name: this.first_name,
                last_name: this.last_name,
                email: this.email,
                phone: this.phone,
                password: this.password
            }).then((response) => {
                this.registration_card = 2;
            }).catch((error) => {
                if (error.data.error.message === "email_already_exists") {
                    let input = this.$refs['email'].$children[0];
                    input.errors.add({field: 'email', msg: 'email already is use'});
                    this.loadingTest = false;

                    console.log(input.errors);
                    console.log(this.loadingTest);
                }

            });

        }.bind(this));
    },
}

this.$validate 这样做:

export default function(scope, arrayOfValues, callback) {

let total = arrayOfValues.length - 1;
let last_item = false;

arrayOfValues.forEach(function(value, index) {
    let input = scope.$refs[value].$children[0];
    input.$validator.validate().then(value => callback(value, total === index, index));
   });
}

我这样做是因为我有自定义输入组件

编辑:这是我使用加载的地方:

<j-button label="Register" :loading="loading" @click.native="register"/>

按钮组件是:

<template>
    <button type="button">
        <span v-if="!loading">{{label}}</span>
        <loading v-if="loading"/>
    </button>
</template>

<script>
import loading from 'vue-loading-spinner/src/components/Circle'

export default {
    name: 'j-button',
    props: [
        'label',
        'loading'
    ],
    components: {
        loading
    }
}
</script>

编辑:更多代码!!!!!!

我的 j 输入组件

<template>
    <div>
        <label v-bind:class="{ 'active': (newValue.length > 0)}">{{label}}</label>
        <input v-bind:class="{ 'error': (errors.has(name))}" type="text" :name="name" v-validate="rules" :placeholder="label" v-model="newValue" v-on:input="updateValue()" ref="input">
        <span v-if="errors.has(name)">{{errors.first(name)}}</span>
    </div>
</template>

<script>
    export default {
        name: 'j-text',
        inject: ['$validator'],
        props: [
            'label',
            'name',
            'rules',
            'value',
        ],
        data() {
            return {
                newValue: ''
            }
        },
        created() {
            this.newValue = this.value;
            this.updateValue();
        },
        methods: {
            updateValue: function () {
                this.$emit('input', this.newValue);
            },
        }
    }
</script>
4

2 回答 2

0

所以我发现了这个问题,为什么仍然很奇怪。我将为此提出另一个问题。它关于我的 j-button 组件:

<template>
    <button type="button">
        <span v-if="!loading">{{label}}</span>
        <loading v-if="loading"/>
    </button>
</template>

<script>
import loading from 'vue-loading-spinner/src/components/Circle'

export default {
    name: 'jellow-button',
    props: [
        'label',
        'loading'
    ],
    components: {
        loading
    }
}
</script>

为了解决这个奇怪的问题,我不得不改变它:

<loading v-if="loading"/>

至:

<loading v-show="loading"/>

如果我改变了这个,那么错误将被加载并且按钮加载图标将在我的捕获中被关闭:

}).catch(error => {
                    if(error.data.error.message === "email_already_exists") {
                        let input = this.$refs['email'].$children[0];
                        input.errors.add({field: 'email', msg: 'email already in use'});
                        this.loading = false;
                    }
                });

但又一次。如果我在按钮中执行 v-if 而不是 v-show,则不会显示错误。很奇怪。我将创建另一个问题,我希望我能得到答案。

于 2018-07-20T11:41:47.787 回答
0

这很简单。只有引用更改会刷新 Vue 视图。

当你这样做时:

new Vue({
    data: ['property'],
    method: {
       change() {
           this.property = "yes"; // will get refreshed
       }
    }
});

视图被刷新(显示更改)。但是,当您更改对象的字段引用(而不是对象本身)或在其上调用方法时,它不会被刷新

 change() {
     this.property.field = "yes"; // won't get refreshed
     this.property.mtehod("yes"); // won't get refreshed
 }

array.push()Vue.js仅对某些特定方法(如)进行了调整,以识别这些方法会刷新视图。如果你想让它工作,你需要调用this.$forceUpdate()或使用Vue.set()来改变 vales。

因此,当您添加错误时,视图不会刷新,只有当您更改数据属性 ( loading) 时,视图才会识别数据值已更改并刷新您的视图。

请阅读Reactivity in Depth,尤其是“如何跟踪更改”一章。请查看哪些设置数据的方式是反应式的,哪些不是。

于 2018-07-20T10:07:38.773 回答