• vue 动态路由实现 后端控制权限时的前端处理


    前端思路: 

    上图中 获取路由信息 ,可以是后端控制的,可以是前端根据用户信息从路由表中筛选的。

    此处讲解后端存储路由信息的情况

    组织路由信息

    请求后台,获取返回结果,结果有两种可能,一种是组合好的树状结构,一种是路由平铺

    树状结构:

    不需要重组路由结构,但是需要替换组件信息

    1. import components from '@/router/components'
    2. /* 遍历后台传来的路由字符串,转换为组件对象
    3. * @params asyncRouterMap MyRoute[] 异步路由数组
    4. * @params type boolean 是否需要重写子路由路径
    5. */
    6. function filterAsyncRouter(asyncRouterMap: MyRoute[], type = false) {
    7. return asyncRouterMap.filter(route => {
    8. if (type && route.children) {
    9. route.children = rewriteChildrenPath(route.children, route)
    10. }
    11. if (route.component) {
    12. // 如果路径组件在路由表中查询不到,默认渲染NotFound组件,其他情况可自定义处理
    13. if (!Object.keys(components).includes(route.component as string)) {
    14. route.component = components.NotFound
    15. } else {
    16. route.component = components[route.component as keyof typeof components]
    17. }
    18. }
    19. if (route.children != null && route.children && route.children.length) {
    20. route.children = filterAsyncRouter(route.children, type)
    21. } else {
    22. delete route[`children`]
    23. delete route[`redirect`]
    24. }
    25. return true
    26. })
    27. }
    28. /* 重写路由中子路由路径
    29. * @params childernMap MyRoute[] 子路由数组信息
    30. * @params lastRouter MyRoute 父路由信息
    31. */
    32. function rewriteChildrenPath(childrenMap: MyRoute[], lastRouter: MyRoute) {
    33. let children: MyRoute[] = []
    34. childrenMap.forEach((el) => {
    35. el.path = `${lastRouter.path }/${ el.path}`
    36. children = children.concat(el)
    37. })
    38. return children
    39. }

     路由平铺

    此时除了替换组件信息,还需要构建树状路由结构

    let routes = res.map(organizeRoute) //organizeMenu 工具函数 重组路由结构
    routes = recursiveData(routes, ``)

    1. import Components from '@/routers/component'
    2. // 菜单组织为route形式
    3. const organizeRoute= (route) => {
    4. // 防止顶级路由未加斜杠报错
    5. const path = route.path.indexOf(`/`) !== 0 ? `/${route.path}` : route.path
    6. const _route= {
    7. //...符合route的属性和其他自定义属性
    8. component: route.component && Components[route.component] || Components.NotFound,
    9. meta: {
    10. title: route.title,
    11. hidden: route.hidden,
    12. icon: route.icon,
    13. //...其他自定义属性
    14. },
    15. query: {},
    16. params: {},
    17. }
    18. // 重定向
    19. route.redirect && Object.assign(_route, { redirect: { name: route.redirect } })
    20. return _route
    21. }
    22. //重组树状路由结构
    23. const organizeRouteTree= (routes, pid = `0`) => {
    24. const _routes= routes.filter(item => item.pid === pid) //找出所有父级路由
    25. if (!_routes|| _routes.length === 0) return []
    26. _routes.sort((prev, next) => {
    27. return prev.sort - next.sort
    28. })
    29. _routes.map(item => {
    30. const children = organizeRouteTree(routes, item.id)
    31. children && children.length > 0 && (item.children = children)
    32. })
    33. return _routes
    34. }

    动态加到路由表

    路由守卫中动态添加

    1. //获取用户信息
    2. userStore.getUserInfo()
    3. .then(() => {
    4. //isRelogin.show = false
    5. perssionStore.getRoutes()
    6. .then(accessRoutes => { //accessRoutes上一步中处理好的树状路由信息
    7. accessRoutes.forEach(route => {
    8. if (!isHttp(route.path)) {
    9. router.addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
    10. }
    11. })
    12. next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
    13. })
    14. })
    15. .catch(err => {
    16. userStore.logOut()
    17. .then(() => {
    18. notification.error({
    19. message: err.code,
    20. description: err.message || err.msg,
    21. })
    22. next({ path: `/` })
    23. })
    24. })
    25. /**
    26. * 判断url是否是http或https
    27. * @param {string} path
    28. * @returns {Boolean}
    29. */
    30. export function isHttp(url:string) {
    31. return url.indexOf(`http://`) !== -1 || url.indexOf(`https://`) !== -1
    32. }

    非路由守卫中添加 

    const createRouter = (routes = []) => {
      const _routes = [...baseRoutes, ...routes]
      return new Router({
        mode: `hash`,
        routes: _routes,
        scrollBehavior: () => ({ y: 0 }),
      })
    }

    const router = createRouter()

    export function resetRouter (routes = []) {
      const newRouter = createRouter(routes)
      router.matcher = newRouter.matcher // the relevant part
    }

  • 相关阅读:
    合工大-人工智能原理实验报告
    0-5V转4-20mA电路
    【树莓派烤肉 001】从 0 开始用自己的树莓派搭建服务器:运维篇
    Mybaitis入门基础(一)MyBatis的概念引入及工作原理
    Motion Tuned Spatio-temporal Quality Assessmentof Natural Videos
    1002 A+B for Polynomials
    新版校园跑腿外卖独立版+APP+小程序前端外卖配送平台源码
    【JDK 8-集合框架进阶】6.1 parallelStream 并行流
    LeetCode刷题---最长回文子串
    小白跟做江科大32单片机之按键控制LED
  • 原文地址:https://blog.csdn.net/weixin_59128282/article/details/126913551