前端vue项目实现动态路由配置

需求:后端根据角色使用路由权限,返回路由表给前端,前端比对路由表筛选匹配路由并添加

  • 用户登录拿到路由表
LoginByUsername({ commit }, userInfo) {
      return new Promise((resolve, reject) => {
        apis
          .loginByUsername(userInfo)
          .then((response) => {
            const data = response
            // 模拟后端暂时未设置权限路由,返回的权限菜单
            !data.jurisdiction.length && (data.jurisdiction = [
              { name: '系统概述', children: [] },
              {
                name: '品牌管理',
                children: [
                  { name: '平台账号管理', children: [] },
                  { name: '人员限制', children: [] },
                  { name: '组织管理', children: [] },
                  { name: '门店管理', children: [] }
                ]
              }
            ])
            commit('SET_USERINFO', data)
            resolve()
          })
          .catch((error) => {
            reject(error)
          })
      })
    },
	// mutations
	SET_JURISDICTION: (state, jurisdiction) => {
      state.jurisdiction = jurisdiction
    },
    // 返回的菜单与侧边栏总菜单比对,并返回相同的路由菜单
    SET_ADDJURISDICTION: (state, Jurisdiction) => {
    // recursionRouter 为比对方法,已封装
      layout.children = recursionRouter(Jurisdiction, layout.children)
      state.addJurisdiction = layout.children
      router.addRoute(layout) // 动态添加可访问路由表
      // 404页面最后添加
      router.addRoute({
        path: '*',
        redirect: '/404'
      })
      // 视图非同步更新,添加此代码可查看添加路由情况
      router.options.routes.push(layout)
      // 旧版添加路由main需为一个数组里面包裹对象
      router.addRoutes(main) // 动态添加可访问路由表
    },
    SET_USERINFO: (state, userInfo) => {
      state.userInfo = userInfo
      localStorage.setItem('userInfo', JSON.stringify(userInfo))
    }
    // actions得addJurisdiction方法
	addJurisdiction({ commit }, addJurisdiction) {
      return new Promise((resolve) => {
      // 比对路由表并添加权限路由
        commit('SET_ADDJURISDICTION', addJurisdiction)
        // 保存后端给的数据
        commit('SET_JURISDICTION', addJurisdiction)
        resolve()
      })
    }
// 引入的layout页面代码
const layout = {
  path: '/layout',
  name: 'Layout',
  component: () => import(/* webpackChunkName: "layout" */ 'views/layout/index.vue'),
  redirect: '/system',
  hidden: true,
  children: [...System, ...BrandManagement, ...ExceptionMonitoring, ...DailyRecord, ...SuperAdmin]
}
export default layout
// recursionRouter方法
// userRouter:后端传递得表, allRouter:前端路由表
export function recursionRouter(userRouter = [], allRouter = []) {
  var realRoutes = []
  allRouter.forEach((v, i) => {
    userRouter.forEach((item, index) => {
      if (item.name === v.meta?.title) {
        if (item.children && item.children.length > 0) {
          v.children = recursionRouter(item.children, v.children)
        }
        realRoutes.push(v)
      }
    })
  })
  return realRoutes
}
  • 在main.js引入文件permission.js 在路由进入之前作权限分析
// permission.js文件
// 由于项目未完全搭建完成,部分判断非最终代码
import router from './router'
import store from './store'

const whiteList = ['/loginPage', '/createAccount', '/forgetpassword', '/404']
router.beforeEach((to, from, next) => {
  let userInfo = store.state.user.userInfo
  if (to.meta?.title) {
    document.title = to.meta.title
  }
  if (!JSON.parse(localStorage.getItem('userInfo'))) {
    if (whiteList.includes(to.path)) {
      console.log(1)
      // 在免登录白名单,直接进入
      next()
    } else {
      console.log(2)
      next('/loginPage') // 否则全部重定向到登录页
    }
  } else {
    if (userInfo.id) {
      if (store.state.user.jurisdiction?.length == 0) {
        console.log(3)
        store.dispatch('addJurisdiction', userInfo.jurisdiction).then((_) => {
          next({ ...to, replace: true })
        })
      } else {
        console.log(4)
        next()
      }
    } else {
      console.log(5)
      store.commit('SET_USERINFO', JSON.parse(localStorage.getItem('userInfo')))
      store.dispatch('addJurisdiction', JSON.parse(localStorage.getItem('userInfo')).jurisdiction).then((_) => {
        next({ ...to, replace: true })
      })
    }
  }
})

踩坑

layout.children = recursionRouter(Jurisdiction, layout.children)
// 本想着深拷贝一份路由表,不修改原来数据。
// 路由添加不能采用JSON.parse(JSON.strigify())序列化,路由里有function方法, 序列化的时候function会丢失
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值