【问题标题】:Axios interceptor - how to return response from vuex storeAxios 拦截器 - 如何从 vuex 商店返回响应
【发布时间】:2020-06-19 02:14:53
【问题描述】:

我有一个登录表单。当用户输入 username/pw 时,axios 拦截器会处理来自 api 的响应,无论是好是坏。

然后响应通过我的 vuex 存储进行路由,在该存储中设置用户凭据。

但是,当我在登录组件中 console.log 响应时,我实际上并没有看到我需要的字段,例如 data, status, headers 等。我看到了这个

在继续登录用户之前,我是否可以通过某种方式验证我的数据是否在商店中?

此时我唯一能想到的就是使用setTimeout 3 秒并调用状态获取器来检索用户数据。我的意思是它有效,但我确信那里有更合适的解决方案

登录.vue

onClickLogin() {
    const userToLogin = {
      username: this.loginForm.username,
      password: this.loginForm.password
    };
    const response = UsersModule.login(userToLogin);

    console.log("response", response); // returns what is pictured in the image above so the if block is technically wrong
    if (response) {
      this.$router.push("/");
    }
  }

axios 请求类

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_URL,
  timeout: 5000
});

service.interceptors.response.use(
  response => {
    return response.data;
  },
  error => {
    Message({
      message: error.message || "Error",
      type: "error",
      duration: 5 * 1000
    });
    return Promise.reject(error);
  }
);

vuex用户登录功能

  @Action({ rawError: true })
  async login(usersSubmit: UserSubmit) {
    const response: any = await loginUser(usersSubmit);
    if (typeof response !== "undefined") {
      const { accessToken, username, name } = response;

      setToken(accessToken);
      this.SET_TOKEN(accessToken);
      this.SET_USERNAME(username);
      this.SET_NAME(name);
    }
  }

从 vuex store 调用 axios 请求的 api 类

export const loginUser = (data: UserSubmit) => {
  return request({
    url: "/auth/login",
    method: "post",
    data
  });
};

【问题讨论】:

    标签: typescript vue.js axios vuex interceptor


    【解决方案1】:

    loginasync 函数,这意味着它返回一个承诺,就像问题描述的那样。

    尤其是异步控制流和 Promise 具有传染性,这要求所有依赖它的调用者也使用 Promise。请注意,login 不返回任何内容,因此它无法解析为响应:

      async onClickLogin() {
        const userToLogin = {
          username: this.loginForm.username,
          password: this.loginForm.password
        };
    
        try {
          await UsersModule.login(userToLogin);
          this.$router.push("/");
        } catch (err) {
          console.error('Login failed');
        }
      }
    

    【讨论】:

    • 在路由到其他地方之前我不需要检查await login 返回的内容吗?基于上面的代码,await 被调用并开始做它的事情,this.$router.push 被立即执行。那么在登录时等待是否有意义?
    • UsersModule.login 被定义为async login(usersSubmit: UserSubmit) {,不是吗?然后可以看到login返回了undefined的promise,里面做了所有必要的副作用,不需要返回结果。如果失败则拒绝并返回错误,否则视为成功。这就是为什么它需要try..catch。不是awaiting,因为它会导致错误的行为,因为 IIUC 需要在设置令牌后进行重定向。
    猜你喜欢
    • 2021-08-06
    • 2021-09-18
    • 2020-06-04
    • 1970-01-01
    • 2018-03-03
    • 2022-01-25
    • 2020-10-22
    • 2020-09-25
    • 2018-09-27
    相关资源
    最近更新 更多