首页 > 解决方案 > 处理 Vuex 操作结果的做法是什么

问题描述

我正在按照本指南使用 Vue 和 Vuex 创建登录系统

https://scotch.io/tutorials/handling-authentication-in-vue-using-vuex#toc-setup-components

这让登录操作返回了一个承诺,我被告知它不遵循 Vuex 所基于的 Flux 模式。

因此,我对其进行了一些更改并执行了以下操作:

// This is the action from my "auth store"
login: ({commit}, userData) => {
  commit('auth_request')
  Api.post('login', userData)
  .then(res => { 
    const token = res.data.data.token
    localStorage.setItem('token', token)
    Api.defaults.headers.common['Authorization'] = "Bearer " + token
    commit('auth_success', token)
  })
  .catch(err => {
    commit('auth_error')
    console.log("Failed to login, check your username or password")
  })    
}

这一切都很好而且花花公子,但是当我在我的应用程序中按下登录按钮时,我看到所有提交都通过了auth_requestauth_success并且存储中充满了来自该auth_success的用户数据。

但是既然我现在没有返回一个承诺,我现在怎么能要求路由器改变视图呢?当系统完成加载时,我没有“反馈”?确认登录成功或失败的最佳做法是什么?

标签: javascriptvue.jsvuex

解决方案


从 Promise 返回是一种反模式的想法是一种 React 驱动的意识形态来推动 Flux 的想法。您将缺少的难题是在最终调用它dispatcher时要听。action

你会听它像一个event listener,像`:

this.$flux.on('login', (data) => {
  //login was called here
})

你会像这样发送它:

this.$flux.emit('login', data)

这个想法是,您并不完全依赖于实际上可能有副作用的单个架构,或者,实际上可能代表整个系统的变化。

不利的一面是您正在向应用程序添加另一层数据管理。您可以在较小的应用程序中完全放弃这一点,只需使用async/awaitwithtry/cache并返回Promise.resolve/reject. 但是,也许您想学习 Flux 模式。在 Vue 中非常简单。

创建一个名为bus.js. 在这个文件中,我们实际上只是创建一个新的 Vue 实例并导出它:

import Vue from 'vue'

const Bus = new Vue({})

export default Bus

现在我们可以继续导入它,比如在我们的登录页面中:

import Bus from 'bus'

在我们的mounted函数中,我们可以添加一个监听器:

Bus.$on('login.success', this.loginHappened)

在我们methods的那个Login组件中,我们可以定义loginHappened.

loginHappened (data) {
  console.log(data)
}

现在我们只需从我们的 Action 中调度它:

// store

import Bus from 'bus'

login: async ({ commit }, userData) => {
  try {
    const res = await Api.post('login', userData)

    const token = res.data.data.token
    localStorage.setItem('token', token)
    Api.defaults.headers.common['Authorization'] = "Bearer " + token
    commit('auth_success', token)

    Bus.$emit('login.sucesss', res.data.data)
  } catch (err) {
    Bus.$emit('login.failure', err.response.data)
  }
}

哦,你还想看看那个失败:

Bus.$on('login.failure', this.loginFailed)

现在在同一个 Login 组件中,或者任何地方,你可以定义那个方法:

loginFailed (error) {
  console.log(error) // the server side data from axios.
}

现在我们有一个系统,其中动作是完全异步和解耦的,我们依靠事件调度和监听器来响应异步动作。

当然,所有这些对于 3 页的 SPA 来说都是多余的。


推荐阅读