解决 Vuex 中异步问题:获取最新的 Token 值
在使用 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 值。
通过下面的代码,我们就可以正常的获取了