问题

在前面有写道使用webpack根据编译环境动态打包不同资源实现生成不同的项目的需求,后经过推敲,发现这个解决方案只适用于单独部署的情况,因为公司项目绝大部分都是使用同一套代码部署的,所以这个方案是不可行的。

方案

最终决定由后端给每个生成租户生成全局唯一的tenant_key,前端根据这个值来动态加载不同的菜单。

步骤

具体代码如下:

// index.js (router)
import menu from '@/const/menuConst'
import menu_jijia from '@/const/menuConst/jijia'
import menu_bilibili from '@/const/menuConst/bilibili'
...
router.beforeEach((to, from, next) => {
  // 清除顶部el-tag
  router.app.$options.store.dispatch("clearFilter");
  const addRouFlag =  router.app.$options.store.getters.addRouFlag;

  // 纯前端路由访问权限控制
  if (to.matched.some(_ => _.meta.requiresAuth)) {
    if (window.localStorage.getItem("token")) {
      if(!addRouFlag) {
        const USERINFO = JSON.parse(window.localStorage.getItem('userinfo'))
        const TENANTKEY = USERINFO.tenant_key;
        if(TENANTKEY) {
          if(TENANTKEY === '7a4c0077f122bf17027d028292963b13') {
            router.app.$options.store.commit("setMenuConst", menu_jijia);
            router.app.$options.store.commit("setAddRouFlag", true);
          }else {
            router.app.$options.store.commit("setMenuConst", menu);
            router.app.$options.store.commit("setAddRouFlag", true);
          }
        }else {
          router.app.$options.store.commit("setMenuConst", menu);
          router.app.$options.store.commit("setAddRouFlag", true);
        }
      }
      next();
    } else {
      next({
        path: "/login",
        redirect: to.fullPath
      });
    }
  } else {
    next();
  }
});

addRouFlag通过vuex控制,在刷新正确的菜单之后关闭,防止反复刷新。根据租户的key不同,再通过vuex修改全局的菜单。以此来达到不同用户加载不同菜单的目的。

拓展知识

以上的方法都是直接通过修改菜单来达到目的的,但是在大型项目中,将所有路由都写在同一个文件中感觉是不太优雅的,于是vue-router的动态路由功能在此就派上用场了。

router-addRoutes方法允许在动态在添加路由规则,所以,我们就可以在此基础上将不同项目的路由区分出来,然后在router.beforeEach中使用这个方法,将特殊化的组件加载到项目中。

疑问

我在项目中也想使用router-addRoutes这个方法,但是我的项目路由除了/login其它的都在/index下,所以组件都在/index路径的children中,在使用这个方法时,特殊页面都成了/index同级,现在还没想到什么解决的办法…