英文:
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>
这种方式下,uid
和 username
无法正确更新。
为了调试,当我在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()
内部,就可以正确更新uid
和username
:
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: {'uid': 'xxx', 'username': 'xxx'}
.
My 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>
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('info');
this.uid = this.temp['username'];
this.username = this.temp['username'];
console.log(this.temp['uid']);
I get a undefined
. But when I add console.log(this.uid)
at the end of require.get()
like this:
//...
.then(response => {
this.temp = response.data;
console.log(this.temp['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['username'];
this.username = this.temp['username'];
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('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');
}
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.uid
和this.username
。
如果您更喜欢使用.then()
,也可以这样做。我已经为两种方法都提供了示例。
我假设 this.uid = data['username']
应该是 this.uid = data['uid']
,所以也已经做了更改。
使用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['username']
was meant to be this.uid = data['uid']
, so changed that too.
With 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();
}
}
With .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();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论