【问题标题】:Vuex: How to wait for action to finish?Vuex:如何等待动作完成?
【发布时间】:2020-07-06 22:33:01
【问题描述】:

我想实现一个登录方法。我的代码是:

login() {
  let user = {
    email: this.email,
    password: this.password
  };

  this.$store.dispatch('auth/login', user)
  console.log(this.$store.getters['auth/getAuthError'])
},

我到达商店并发送登录操作的地方。

商店里的动作是这样的:

login(vuexContext, user) {
        return axios.post('http://localhost:8000/api/user/login', user)
        .then(res => {
            vuexContext.commit('setToken', res.data.token)
            vuexContext.commit('setUser', res.data, {root: true})
            localStorage.setItem('token', res.data.token)
            Cookie.set('token', res.data.token )
            this.$router.push('/')
        }).catch(err => {
            vuexContext.commit('setAuthError', err.response.data)
        })
    },

在 catch 块中,如果发生错误,我会更新状态并将authError 属性设置为我得到的错误。

我的问题是,在登录方法中,console.log 语句在操作实际完成之前执行,因此authError 属性是尚未设置的状态。 如何解决这个问题?

【问题讨论】:

    标签: vue.js vuex


    【解决方案1】:

    您的action 正在返回 promise,因此您可以在控制台 承诺已在 then() 块中解决。

    login() {
      let user = {
        email: this.email,
        password: this.password
      };
    
      this.$store.dispatch('auth/login', user).then(() => {
       console.log(this.$store.getters['auth/getAuthError'])
       // this.$router.push('/') // Also, its better to invoke router's method from a component than in a store file, anyway reference of a component may not be defined in the store file till you explicity pass it
      })
    },
    

    或者,您可以将 login 设为 async 函数和 wait 用于 action 直到 promise 操作返回的已解决

    async login() {
      let user = {
        email: this.email,
        password: this.password
      };
    
      await this.$store.dispatch('auth/login', user)
      console.log(this.$store.getters['auth/getAuthError'])
    },
    

    【讨论】:

    • 如果我们使用您的第一个示例(.then on action),由于该操作中有一个承诺(axios),组件中的 .then 将在数据处于正确状态之前执行?
    • nvm 我从操作中返回了承诺,然后 .then 在组件中工作
    【解决方案2】:

    您可以使用 async-await 代替 Promise.then。但我的建议是不要在店内使用 Axios。在登录方法里面调用axios,然后调用store。像这样的:

    methods: {
        async login() {
            try {
                const result = await axios.post('http://localhost:8000/api/user/login', this.user);
                this.$store.dispatch('auth/login', result);
            } catch (err) {
                console.log(err);
            }
        }
    }
    

    然后你只需要在你的商店中设置对象。

    【讨论】:

    • 为什么用户 axios 不在商店里?
    • 这不是一个好的编码习惯。在编程基础中,我们有一个称为关注点分离的设计原则,它说文件/函数应该只处理一个角色。就您而言,Vuex 正在管理商店和 API。
    猜你喜欢
    • 2020-05-15
    • 2019-11-06
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    相关资源
    最近更新 更多