(Vue) Axios 设置数据不适用于 2 个属性。我无法解释为啥

Posted

技术标签:

【中文标题】(Vue) Axios 设置数据不适用于 2 个属性。我无法解释为啥【英文标题】:(Vue) Axios set data not working with 2 properties. I can't explain why(Vue) Axios 设置数据不适用于 2 个属性。我无法解释为什么 【发布时间】:2018-12-28 13:15:15 【问题描述】:

我遇到了我遇到过的最奇怪的错误。我在我的 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 仍然为 false,因为我希望不显示我的加载图标。任何人对此都有解释。

编辑:更多代码

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-input 组件

<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>

【问题讨论】:

console.log(this.loading) 给你什么? 如果this.loading = false,则为false,否则为true,因为它被设置为函数的开始 你能分享你的html和整个vue doc吗?您是否检查过加载时没有隐藏错误的 v-if @Marcus 这不是 html 问题。因为当我在我的代码中执行 console.log(input.errors) 时。添加 this.loading = false 时,错误数组为空。当我移除那个加载部分时。然后我的错误数组将得到错误项。编辑:在我看来,我也有这个 this.errors。相同的故事。没有 this.loading = false。我有错误项目。当 this.loading = false 设置在 axios 部分。错误数组中没有项目。 好的,很高兴看到整个代码,你是否使用观察者来做任何事情 【参考方案1】:

这很简单。只有引用更改会刷新 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
 

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

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

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

【讨论】:

但是当我删除 this.loading = false 时。将显示错误。在成功部分(.then)中,我也更改了 this.registartion_card = 2 并且也有效。 如果我只做 this.loading = false,不添加错误。这个,加载也是假的,加载图标会消失 简短的说法。如果我使用 2 个更改中的 1 个。有用。但是如果 a 想要两者都发生变化,则只会触发 this.loading。 (不管我把代码按什么顺序) @NielsLucas 你能告诉我们你的模板吗?$refs['email'].$children[0] 到底是什么? 它是一个自定义输入组件。我已经在我的问题中添加了。【参考方案2】:

所以我发现了这个问题,但为什么仍然很奇怪。我将为此提出另一个问题。关于我的 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,则不会显示错误。很奇怪。我将创建另一个问题,希望能得到答案。

【讨论】:

以上是关于(Vue) Axios 设置数据不适用于 2 个属性。我无法解释为啥的主要内容,如果未能解决你的问题,请参考以下文章

Axios POST 调用不适用于 JWT 令牌,而 GET 调用有效

tns 预览不适用于带有 nativescript-vue 的 android

Laravel 表单请求验证规则“必需”不适用于空值

从请求响应创建 PDF 不适用于 axios,但适用于本机 xhr

POST 请求适用于 Postman,但不适用于 axios.post()

Vue 2 单文件组件不适用于仅运行时构建