在使用 Vuex 管理状态时,有时会遇到异步问题,特别是在获取异步数据并将其保存到 Vuex 中后,立即获取该数据时可能会出现问题。在这篇文章中,我们将讨论如何解决这个问题,并确保在获取 Token 值时始终获取到最新的值。
假设我们有一个 Vuex 模块 auth
,其中包含了登录、登出和检查 Token 的方法。在登录成功后,我们将 Token 保存到 Vuex 的状态中,并且在需要的时候从状态中获取 Token 值。
const auth = {
state: {
token: null
},
mutations: {
SET_TOKEN(state, token) {
state.token = token;
},
CLEAR_TOKEN(state) {
state.token = null;
}
},
actions: {
login({ commit }, loginForm) {
return new Promise((resolve, reject) => {
// 调用登录接口,传递登录表单数据
axios.post('http://localhost:8989/user/login', loginForm)
.then(response => {
const token = response.data.data.token;
// 将token保存到Vuex中
commit('SET_TOKEN', token);
// 将token保存到浏览器的localStorage中,以便在刷新页面后仍然可以保持登录状态
localStorage.setItem('token', token);
resolve();
})
.catch(error => {
reject(error);
});
});
},
logout({ commit }) {
// 清除token并重定向到登录页面
commit('CLEAR_TOKEN');
localStorage.removeItem('token');
router.push('/');
},
checkToken({ commit }) {
const token = localStorage.getItem('token');
if (token) {
// 将token保存到Vuex中
commit('SET_TOKEN', token);
} else {
// 如果没有token,则重定向到登录页面
router.push('/');
}
},
getToken(){
console.log("我被调用了")
return this.state.token;
}
}
};
在上述代码中,我们把getToken这个方法放在了,Action中,这就会导致一个问题,就是虽然我们登录成功之后,token也set成功了,但是了,当我们取token的时候,会发现这个token为空值。
由于异步问题,当我们立即调用 getToken
方法时,它可能会返回 null
值,因为在调用 getToken
时,SET_TOKEN
方法可能还没有被调用。
为了解决这个问题,我们需要将 getToken
方法移到 state
中,并定义一个 getter
来获取 Token 的值。这样,在调用 getToken
时,它会返回最新的 Token 值。
修改后的代码如下:
const auth = {
state: {
token: null
},
mutations: {
SET_TOKEN(state, token) {
state.token = token;
},
CLEAR_TOKEN(state) {
state.token = null;
}
},
actions: {
login({ commit }, loginForm) {
return new Promise((resolve, reject) => {
// 调用登录接口,传递登录表单数据
axios.post('http://localhost:8989/user/login', loginForm)
.then(response => {
const token = response.data.data.token;
// 将token保存到Vuex中
commit('SET_TOKEN', token);
// 将token保存到浏览器的localStorage中,以便在刷新页面后仍然可以保持登录状态
localStorage.setItem('token', token);
resolve();
})
.catch(error => {
reject(error);
});
});
},
logout({ commit }) {
// 清除token并重定向到登录页面
commit('CLEAR_TOKEN');
localStorage.removeItem('token');
router.push('/');
},
checkToken({ commit }) {
const token = localStorage.getItem('token');
if (token) {
// 将token保存到Vuex中
commit('SET_TOKEN', token);
} else {
// 如果没有token,则重定向到登录页面
router.push('/');
}
}
},
getters: {
getToken(state) {
return state.token;
}
}
};
在组件中,我们可以通过 this.$store.getters.getToken
来获取最新的 Token 值。
通过下面的代码,我们就可以正常的获取了