我是怎么做动态菜单、路由权限的

745 阅读2分钟

这是我参与12月更文挑战的第24天,活动详情查看:2021最后一次更文挑战

在我做 SDK 之前,我也是写 VUE 的,要是说有值得说的,那我来说说,当年我是怎么基于 VUE、Vue Router、VUEX,做 SAAS 系统菜单权限的。

前提:这是个基于 VUE 做得 SAAS 系统,该系统需要根据当前用户,做动态菜单权限、动态按钮权限,我们来一起看看动态菜单权限是如何实现的。

动态菜单权限实现思路

首先,动态菜单权限,是基于 Vue Router 来进行实现的,要想实现动态菜单权限,步骤如下:

  1. 保存一个无需权限的路由,比方说登录页、无状态首页等;
  2. 保存一个需要权限的路由,将此路由与服务端传来的菜单权限树数据进行比对,将比对后的路由,执行 router.addRoutes 方法,添加到原始路由中,此时已可以通过路由对页面进行访问;
  3. 将比对后的路由,与无状态路由 push 到一个数组里,通过 VUEX 进行数据传输,通过数据的双向绑定,将完整路由地址作用到 menuList 上,实现左侧菜单的路由权限显示。
  4. 这一切依赖于 Vue Router 的钩子函数 —— beforeEach(前置路由守卫)和 VUEX 来实现。

当然,做着一切的时候,也不是完全顺畅的,遇到的主要问题就是刷新页面404问题,我是如何解决的呢。

刷新后页面404问题如何解决

刷新后页面404,
之前的解决方法,是查看路由是否有匹配值,如果没有,则执行 router.addRoutes 方法,对路由进行重新添加,代码如下:

router.beforeEach((to, from, next) => {
  if (to.matched.length === 0) {
    const menu = JSON.parse(localStorage.getItem('menu'))
    router.addRoutes(recursionRouter(menu, allPermissionsRouter))
    next({ path: to.path, query: to.query })
  } else {
    next()
  }
})

现在的解决办法是在 router.onReady 钩子下,执行 router.addRoutes 方法,代码如下:

router.onReady(() => {
    const menu = JSON.parse(localStorage.getItem('menu'))
    router.addRoutes(recursionRouter(menu, allPermissionsRouter))
    next({ path: to.path, query: to.query })
})

其实还有个问题,是菜单权限只在登录接口给到,没有单独暴露接口,导致这边只能在重新登录的时候进行菜单权限更新,但是从产品角度来说,可能也不算是问题,因为重新登录后再切换菜单权限,好像也能说得过去,这个就这样过去了。