iview admin动态路由

感谢这篇文章:https://blog.csdn.net/weixin_34179968/article/details/92579951
网上找到了好多文章就这篇靠谱点,只少能靠这篇文章把功能做出来。唯一缺点就是提供的代码没有后端,程序跑不起来。不过还好,有代码参考也不错。
这里我不得不吐槽一下网上有的文章,太TMD坑,甚至还有故意留坑让你自己去排查的,心中简直就是万马奔腾的赶脚~

设计思路

  1. 通过改造获取用户信息接口,有用户信息接口提供用户信息和菜单权限,并将菜单权限存到本地(user.js文件改造)
  2. 改造本地路由(router.js文件改造)
  3. 添加菜单解析方法(util.js添加方法)
    就这么简单,只需要这三步就行了,不知道网上的怎本写的那么复杂。

开始改造

1、将获取到的菜单存到本地缓存(user.js改造),用户登录成功后将菜单存到本地
引入localSave方法
在这里插入图片描述
将数据存到本缓存(这个数据是由后端返回的,你可以先直接写个死数据在这)
在这里插入图片描述
如果你还没开始对接后端的话,那就直接考下面代码替换黄色的部分即可
            var menus = [  {
              path: '',
              name: 'doc',
              meta: {
                access: ['超级管理员'],
                title: '文档',
                href: 'https://lison16.github.io/iview-admin-doc/#/',
                icon: 'ios-book'
              }
            },
            {
              path: '/join',
              name: 'join',
              component: 'components/main',//注意,这一步很重要Main必须这样替换掉
              children: [
                {
                  path: 'join_page',
                  name: 'join_page',
                  meta: {
                    icon: '_qq',
                    title: 'QQ群'
                  },
                  component: 'view/join-page.vue'
                }
              ]
            }];

            //将菜单存到本地
            localSave('userRouters',JSON.stringify(menus))
2、router.js改造
1、引入localRead和backendMenusToRouters 方法
2、原来的js进行拆分,拆分成系统菜单和业务菜单,比如404、401、500、登录之类的菜单就不需要放进行数据库,直接放这本地就行了
在这里插入图片描述
sysRoutes存是本地菜单
//后端返回的用户菜单
export const userRoutes = () => {
  //从本地缓存中拿取菜单
  var jsonRouters = localRead('userRouters');
  //将本地json数据转成json对象后,再通过backendMenusToRouters方法处理component
  return jsonRouters ? backendMenusToRouters(JSON.parse(jsonRouters)) : []
}

export default [ ...userRoutes(), ...sysRoutes];
2、util.js改造
1、添加下面这段代码拷进去就行了
//#region 动态路由处理
/**
 * @description 将后端菜单树转换为路由树
 * @param {Array} menus
 * @returns {Array}
 */
export const backendMenusToRouters = (menus) => {
  let routers = []  
  forEach(menus, (menu) => {
    // 将后端数据转换成路由数据
    let route = backendMenuToRoute(menu)
    // 如果后端数据有下级,则递归处理下级
    if (menu.children && menu.children.length !== 0) {
      route.children = backendMenusToRouters(menu.children)
    }
    routers.push(route)
  })
  return routers
}

/**
 * @description 将后端菜单转换为路由
 * @param {Object} menu
 * @returns {Object}
 */
const backendMenuToRoute = (menu) => {
  // 原先routers写法是component: () => import('@/view/error-page/404.vue')
  let route = Object.assign({}, menu)
  if(route.component)
    route.component = () => import(`@/${menu.component}`)
  return route
}

//#endregion

#到这里需要用到的代码就贴完了

注意!注意!注意!:这个很重要,一定要看!
原始前端代码:

component: () => import('@/view/join-page.vue')

component: Main,

改造后(数据库里只能存下面这种代码):

component: 'view/join-page.vue'

component: 'components/main',

我遇到的最大困难就是不知道怎么将后端代码转成前端对象,不然我都不用到网上去翻代码了,哎,怪自己js功底不够扎实啊~

“component:Main”必须存全路径“component: ‘components/main’”。或者存成“component: ‘Main’”,注意Main是用单引号引起来的哦!
我参考的这篇文章的代码是针对Main、parentView做单独处理,而且必须要引入(import)相应的文件。我觉得这样不好,如果要使用其他公共的文件就得改代码,所以我直接使用全路径(components/main)。

外部代码参考

import Main from '@/components/main' // Main 是架构组件,不在后台返回,在文件里单独引入
import parentView from '@/components/parent-view' // 获取组件的方法

// @函数: 遍历后台传来的路由字符串,转换为组件对象
export const filterAsyncRouter = asyncRouterMap => {
  const accessedRouters = asyncRouterMap.filter(route => {
    if (route.component) {
      if (route.component === 'Main') {
        // Main组件特殊处理
        route.component = Main
      } else if (route.component === 'parentView') {
        // parentView组件特殊处理
        route.component = parentView
      } else {
        // route.component = _import(route.component)
        route.component = lazyLoadingCop(route.component)
      }
    }
    if (route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children)
    }
    return true
  })
  return accessedRouters
}

其他唠嗑

不赶时间的话可以继续看下》》》

原本我是想把菜单存到user的state中的,但是有几个问题,
1、刷新后state数据会丢失
2、state和菜单不是双向绑定的,由于存进去是异步的,数据还没开始存菜单就已经加载出来,等数据存进去后菜单也不能自动加载出来。这里的问题就是:存进去后我不知道应该怎么通知菜单重新将新增加载新菜单。
3、这里还有个问题就是菜单是由用户信息接口返回过来的,可以单独做一个接口来获取用户菜单。主要是这个项目不是高并发的业务量也不大,为了节省时间就把他简化了

发现BUG了

登录后没有菜单,必须刷新后才显示

我做了以下整改
  1. 将菜单存储改成登录成功后存储到本地(跟这个BUG没关系,只是这样可以减少接口调用)
  1. 添加下面两行代码在这里插入图片描述
  1. app.js修改这3个地方
    在这里插入图片描述

FK还是有BUG

菜单是正常显示出来了,但是点了菜单后提示401(无权限)错误
不想搞了,来个终极的,登录成功后不用路由跳转,用href来跳转,搞定!
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值