vue后台管理系统权限解决方案

最近项目的权限管理用到了vue-router的addRoutes方法,这里记录一下
业务场景
1.用户登陆 — 获取权限 — 判断权限 — 生成动态路由
2.用户刷新,停留在原页面
3.用户退出 — 重新登陆 — 获取权限 — 判断权限 — 生成新的动态路由

遇到的坑

1.重新登陆生成动态路由时,vue-router提示 [vue-router] Duplicate named routes definition:*在这里插入图片描述
2.跳转到生成的动态路由,然后点击刷新,发现路径是对的,但是页面却显示404

坑点1解决方法

第一个问题是因为当我们第一次登陆后就把生成的动态路由添加到router中,但是退出再登陆并没有清空添加的动态路由,官方只提供 addRoutes 方法,但是并没有提供清除路由的方法。路由重复了,所以就报错了。

解决方法:

  • 首先在router/index.js 文件中写入下面的方法
// router/index.js
// 重置路由
router.$addRoutes = (params) => {
  router.matcher = new VueRouter({ mode: 'history' }).matcher
  router.addRoutes(params)
}
  • 然后在添加动态路由的地方使用
router.$addRoutes([...routes, ...routeLists])
// routes 是基础路由
// routeLists 是动态生成的路由

坑点2解决方法

因为路由是放到状态管理里面的,所以浏览器一刷新,就会清空状态管理,没有了动态生成的路由,就会跳转到错误页。

解决方法:

  • 监听路由的beforeEach,并利用vuex判断是否已经加载过权限了,如果没有加载过,就重新获取接口,并动态生成路由
// router/index.js
router.beforeEach(async (to, from, next) => {
  if (!store.state.mod.permission.permissionLoaded) {
    // console.log('未加载权限')
    await store.dispatch('mod/permission/isLoaded')
  }
  next()
})
// permission.js
export default {
  namespaced: true,
  state: {
    // 是否加载过权限
    permissionLoaded: false,
    // 权限路由信息
    perRouteLists: []
  },
  actions: {
    // 判断是否加载过路由信息
    isLoaded ({ state, dispatch }) {
      return new Promise(async resolve => {
        if (state.permissionLoaded) {
          resolve()
          return
        }
        // 要先把permissionLoaded设置未true,否则可能会死循环
        state.permissionLoaded = true
        await dispatch('initRoutes')
        resolve()
      })
    },
    // 获取权限列表
    initRoutes ({ state, commit, dispatch }) {
      return new Promise((resolve, reject) => {
        // 获取权限列表
	    return GetPermission().then(async res => {
	      if (res && res.code === 200) {
	        // formatRoutes方法用于格式化路由格式
	       	let routeLists = formatRoutes(menus)
	        state.perRouteLists = routeLists
	        // 把路由放到全局
	        await router.$addRoutes([...routes, ...routeLists])
          }
        }).catch(err => {
          reject(err)
        })
      })
    }
  },
  mutations: {
  }
}
  • 万事俱备,赶紧刷新试一试,发现又gg。明明已经添加了动态路由,但是还是没用?在beforeEach方法中把 路由去向打印出来,发现name是 404,what?明明是在人员管理页啊,难道在还没生成动态路由前,想要跳转‘/user’,但是这个路由并不存在,所以就跳转到了错误页(猜测)?

在这里插入图片描述

  • 接着在生成动态路由后使用 ==router.replace(to.path)==竟意外解决了,神奇!
// router/index.js
router.beforeEach(async (to, from, next) => {
  if (!store.state.mod.permission.permissionLoaded) {
    // console.log('未加载权限')
    await store.dispatch('mod/permission/isLoaded')
    router.replace(to.path)
  }
  next()
})
原创文章 16 获赞 12 访问量 2682

猜你喜欢

转载自blog.csdn.net/weixin_44775548/article/details/98063486