用于重定向未授权的vuex操作的模式

时间:2018-02-01 20:04:31

标签: javascript design-patterns vue.js vuex

Navigation guards非常适合将未经授权的用户重定向到登录页面,但是如何将未经授权的vuex操作重定向到登录页面呢?

我可以在vue方法中轻松地做到这一点,我可以像这样调用动作:

  if (!this.isLoggedIn) {
    this.$router.push({ name: 'login', query: { comeBack: true } })
    $(`.modal`).modal('hide')
    return
  }

但是我要为每个需要授权的组件方法插入这5行代码。

我能想到的所有解决方案听起来都很糟糕,所以我想知道vuex的方式是什么:

  1. 为了在vuex操作级别拒绝它,我必须调出$ router实例,并且仍然需要为每个需要auth的操作重用5行。

    < / LI>
  2. 我可以在实用程序文件中处理此问题,但后来我在该文件中处理$ router实例。

  3. 我可以使用全局vue mixin并在拨打电话之前调用它(a),然后再次(b)从服务器返回401时。

  4. 所有这些看起来很奇怪。我错过了什么vuex方式?

1 个答案:

答案 0 :(得分:2)

这听起来像是middleware的工作。不幸的是,Vuex没有正式的方法来做中间件。

有一个subscribeAction()但是在提交后运行,因此不允许mods操作。还有一项提案Middleware processing between actions and mutation

正如我所看到的,我们希望中间件能够做两个通用的事情

  • 取消行动
  • 允许调用替代操作

如果没有修补store.dispatch()或者在创建商店后弄乱私有财产_actions,第二个很难做到。

但是,为了保护你描述的动作,我们只需要能够取消它。

这是我喜欢的Vuex商店modules pattern的穷人中间件。

从模块存储构建

export const store = new Vuex.Store({
  modules: {
    config,
    pages: applyMiddleware(pages),
    measures,
    user,
    loadStatus,
    search
  }
})

<强> applyMiddleware

const applyMiddleware = function(module) {
  if(module.middlewares) {
    Object.values(module.middlewares).forEach(middlewareFn => {
      Object.keys(module.actions).forEach(actionName => {
        const actionFn = module.actions[actionName]
        module.actions[actionName] = addMiddleware(actionName, actionFn, middlewareFn)
      });
    })
  }
  return module;
}

<强> addMiddleware

const addMiddleware = function(actionName, actionFn, middlewareFn) {
  return function(context, payload) {
    const resultFn = middlewareFn(actionFn)
    if(resultFn) {
      resultFn(context, payload)
    }
  }
}

在模块中定义中间件

const actions = {
  myAction: (context, payload) => {
    ...
    context.commit('THE_ACTION', payload)
    ...
  },
}

const middlewares = {
  checkAuthMiddleware: (action) => {
    return this.isLoggedIn 
      ? action // if logged-in run this action
      : null;  // otherwise cancel it
  }
}

export default {
  state,
  getters,
  mutations,
  actions,
  middlewares
}

此实现具有特定于模块的中间件功能,但您也可以全局定义它们并应用于适用的模块。