Vue.js为什么不会更新data中的变量?

huangapple go评论59阅读模式
英文:

Why does Vue.js not update variables inside data

问题

无法在Vue的data中更新变量

我正在使用Vue 3作为前端创建项目。

在Dashboard.vue中,将使用头部的令牌发送一个GET请求到后端,以便让后端识别用户的身份,然后Vue将接收包含信息的JSON响应,例如:{'uid': 'xxx', 'username': 'xxx'}

我的Dashboard.vue:

<script>
import axios from 'axios';

export default {
    data() {
        return {
            uid: '',
            username: '',
            temp: {},
            loaded: false
        }
    },
    methods: {
        require_get(url) {
            var token = localStorage.getItem('token');
            var config = {
                headers: {
                    'token': token,
                }
            };
            var _url = 'user/dashboard/' + url;
            axios.get(_url, config)
            .then(response => {
                this.temp = response.data;
            })
        },
        get_user_info() {
            this.require_get('info');
            this.uid = this.temp['username']; 
            this.username = this.temp['username'];
        }
    },

    mounted() {
        this.get_user_info();
    }
}
</script>

这种方式下,uidusername 无法正确更新。

为了调试,当我在get_user_info()的末尾添加console.log(this.uid),如下所示:

//...
this.require_get('info');
this.uid = this.temp['username']; 
this.username = this.temp['username'];
console.log(this.temp['uid']);

我得到了一个undefined。但是当我在require.get()的末尾添加console.log(this.uid),如下所示:

//...
.then(response => {
    this.temp = response.data;
    console.log(this.temp['uid']);
})

输出显示变量uid在此时已经更新。

经过测试,我发现只要我把以下两行代码放在require_get()内部,就可以正确更新uidusername

this.uid = this.temp['username']; 
this.username = this.temp['username'];

为什么会这样?我如何能够在get_user_info()中保持这两行代码,并成功更新这些变量?

更新

我将我的代码更改为:

methods: {
    async require_get(url) {
        var token = localStorage.getItem('token');
        var config = {
            headers: {
                'token': token,
            }
        };
        var _url = 'user/dashboard/' + url;
        axios.get(_url, config)
        .then(response => {
            return response.data;
        })
    },
    async get_user_info() {
        let info = await this.require_get('info');
        console.log(info);
        this.uid = info['username']; 
        this.username = info['username'];
    }
},

mounted() {
    this.get_user_info('info');
}

并且console.log(info)的输出仍然是undefined,现在我不明白为什么会这样...

英文:

Can't update variables inside data in Vue

I'm creating a project using Vue 3 as frontend.

In Dashboard.vue, a GET request will be sent to backend with token in header, in order to let the backend identify user's identity, then Vue will receive the response with a json including info like this: {&#39;uid&#39;: &#39;xxx&#39;, &#39;username&#39;: &#39;xxx&#39;}.

My Dashboard.vue:

&lt;script&gt;
import axios from &#39;axios&#39;;

export default {
    data() {
        return {
            uid: &#39;&#39;,
            username: &#39;&#39;,
            temp: {},
            loaded: false
        }
    },
    methods: {
        require_get(url) {
            var token = localStorage.getItem(&#39;token&#39;);
            var config = {
                headers: {
                    &#39;token&#39;: token,
                }
            };
            var _url = &#39;user/dashboard/&#39; + url;
            axios.get(_url, config)
            .then(response =&gt; {
                this.temp = response.data;
            })
        },
        get_user_info() {
            this.require_get(&#39;info&#39;);
            this.uid = this.temp[&#39;username&#39;]; 
            this.username = this.temp[&#39;username&#39;];
        }
    },

    mounted() {
        this.get_user_info();
    }
}
&lt;/script&gt;

In this way, uid and username cannot be updated correctly.

For debugging, when I add console.log(this.uid) at the end of get_user_info() like this:

//...
this.require_get(&#39;info&#39;);
this.uid = this.temp[&#39;username&#39;]; 
this.username = this.temp[&#39;username&#39;];
console.log(this.temp[&#39;uid&#39;]);

I get a undefined. But when I add console.log(this.uid) at the end of require.get() like this:

//...
.then(response =&gt; {
                this.temp = response.data;
                console.log(this.temp[&#39;uid]);
            })

The output shows that variable uid has already been updated at this moment.

After testing, I found that I can correctly update uid and username as long as I put

this.uid = this.temp[&#39;username&#39;]; 
this.username = this.temp[&#39;username&#39;];

inside require_get().
Why is that? And how can I manage to update these variables with these two codes staying in get_user_info()?

Update

I changed my codes into"

    methods: {
        async require_get(url) {
            var token = localStorage.getItem(&#39;token&#39;);
            var config = {
                headers: {
                    &#39;token&#39;: token,
                }
            };
            var _url = &#39;user/dashboard/&#39; + url;
            axios.get(_url, config)
            .then(response =&gt; {
                return response.data;
            })
        },
        async get_user_info() {
            let info = await this.require_get(&#39;info&#39;);
            console.log(info);
            this.uid = info[&#39;username&#39;]; 
            this.username = info[&#39;username&#39;];
        }
    },

    mounted() {
        this.get_user_info(&#39;info&#39;);
    }

and the output of console.log(info) is still undefined, now I don't understand...

答案1

得分: 0

问题是异步执行。

require_get函数中,您在.then()回调中更新了this.temp,该回调仅在Promise已经_解决_时才被调用。在get_user_info函数中,您调用了require_get,然后立即(同步地)尝试读取数据。因为它是异步获取和设置的,所以它还没有准备好,您会得到undefined

要修复这个问题,将require_get改成一个异步函数,并返回数据而不是使用this.temp。然后也将get_user_info改成一个异步函数,等待调用require_get,并将返回的数据分配给this.uidthis.username

如果您更喜欢使用.then(),也可以这样做。我已经为两种方法都提供了示例。

我假设 this.uid = data[&#39;username&#39;] 应该是 this.uid = data[&#39;uid&#39;],所以也已经做了更改。

使用async/await

import axios from 'axios';

export default {
    data() {
        return {
            uid: '',
            username: '',
            loaded: false
        }
    },
    methods: {
        async require_get(url) {
            var token = localStorage.getItem('token');
            var config = {
                headers: {
                    'token': token,
                }
            };
            var _url = 'user/dashboard/' + url;
            var response = await axios.get(_url, config);
            return response.data;
        },
        async get_user_info() {
            var data = await this.require_get('info');
            this.uid = data['uid']; 
            this.username = data['username'];
        }
    },

    mounted() {
        this.get_user_info();
    }
}

使用.then()

import axios from 'axios';

export default {
    data() {
        return {
            uid: '',
            username: '',
            loaded: false
        }
    },
    methods: {
        require_get(url) {
            var token = localStorage.getItem('token');
            var config = {
                headers: {
                    'token': token,
                }
            };
            var _url = 'user/dashboard/' + url;
            return axios.get(_url, config).then((response) => response.data);
        },
        get_user_info() {
            this.require_get('info').then((data) => {
                this.uid = data['uid']; 
                this.username = data['username'];
            });
        }
    },

    mounted() {
        this.get_user_info();
    }
}
英文:

The issue is asynchronous execution.

In require_get, you update this.temp in the .then() callback, which is only called when the Promise has resolved. In get_user_info, you are calling require_get and then immediately (synchronously) trying to read the data. Because it is fetched and set asynchronously, it is not yet present and you get undefined.

To fix it, make require_get an async function and return the data instead of using this.temp. Then make get_user_info an async function as well, await the call of require_get, and assign this.uid and this.username to the returned data.

You could also use .then() if you prefer that to async/await. I have included examples for both.

I assume that this.uid = data[&#39;username&#39;] was meant to be this.uid = data[&#39;uid&#39;], so changed that too.

With async/await

import axios from &#39;axios&#39;;

export default {
    data() {
        return {
            uid: &#39;&#39;,
            username: &#39;&#39;,
            loaded: false
        }
    },
    methods: {
        async require_get(url) {
            var token = localStorage.getItem(&#39;token&#39;);
            var config = {
                headers: {
                    &#39;token&#39;: token,
                }
            };
            var _url = &#39;user/dashboard/&#39; + url;
            var response = await axios.get(_url, config);
            return response.data;
        },
        async get_user_info() {
            var data = await this.require_get(&#39;info&#39;);
            this.uid = data[&#39;uid&#39;]; 
            this.username = data[&#39;username&#39;];
        }
    },

    mounted() {
        this.get_user_info();
    }
}

With .then()

import axios from &#39;axios&#39;;

export default {
    data() {
        return {
            uid: &#39;&#39;,
            username: &#39;&#39;,
            loaded: false
        }
    },
    methods: {
        require_get(url) {
            var token = localStorage.getItem(&#39;token&#39;);
            var config = {
                headers: {
                    &#39;token&#39;: token,
                }
            };
            var _url = &#39;user/dashboard/&#39; + url;
            return axios.get(_url, config).then((response) =&gt; response.data);
        },
        get_user_info() {
            this.require_get(&#39;info&#39;).then((data) =&gt; {
                this.uid = data[&#39;uid&#39;]; 
                this.username = data[&#39;username&#39;];
            });
        }
    },

    mounted() {
        this.get_user_info();
    }
}

huangapple
  • 本文由 发表于 2023年6月2日 12:22:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76387093.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定