Solve the asynchronous problem in Vuex: get the latest Token value

Solve the asynchronous problem in Vuex: get the latest Token value

When using Vuex to manage state, you can sometimes run into asynchronous issues, especially when fetching asynchronous data immediately after fetching it and saving it into Vuex. In this article, we will discuss how to solve this problem and ensure that when getting the Token value, you always get the latest value.

problem background

Suppose we have a Vuex module auththat contains methods for logging in, logging out, and checking tokens. After the login is successful, we save the Token in the state of Vuex, and get the Token value from the state when needed.

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

In the above code, we put the getToken method in the Action, which will cause a problem, that is, although we successfully log in, the token is also set successfully, but when we get the token, we will find this token is null.

Due to asynchronous issues, when we call getTokenthe method immediately, it may return nullthe value, because at the time of the call getToken, SET_TOKENthe method may not have been called yet.

solution

To solve this problem, we need to getTokenmove the method stateto and define a getterto get the value of Token. In this way, when is called getToken, it will return the latest Token value.

The modified code is as follows:

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

In the component, we can use this.$store.getters.getTokento get the latest Token value.

Through the following code, we can get it normally

insert image description here

Guess you like

Origin blog.csdn.net/qq_51447496/article/details/132452404