首页 文章

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

提问于
浏览
1

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

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

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

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

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

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

  • 我可以在实用程序文件中处理这个问题,但后来我在该文件中处理$ router实例 .

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

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

1 回答

  • 2

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

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

    在我看来,我们希望中间件能够做两件通用的事情

    • 取消动作

    • 允许调用替代操作

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

    但是,为了保护您描述的操作,我们只需要能够取消它 .


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

    store construction from modules

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

    defining middleware in the module

    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
    }
    

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

相关问题