基于iview-admin实现动态路由的示例代码


Posted in Javascript onOctober 02, 2019

iview-admin是一个基于vue和iview组件库实现的管理后台前端,本文基于iview-admin最新版本,实现基于权限的动态路由加载。

本文代码可参见:https://github.com/MayBeWrong/iview-admin-dynamic-router

背景:

动态路由:vue的路由,可通过new Router传入路由数组定义实现,也可以通过router.addRoutes实现。通过router.addRoutes动态传入路由定义的方式,称之为动态路由。路由数据可以全部保存在后台数据库中,也可以将路由配置在前端,后端返回给前端路由权限信息,然后匹配过滤,进行加载。本文就这两种方式分别进行介绍,并且给出实现参考。

目标:

基于iview-admin最新代码,实现两种不同的路由动态加载方式:

  1. 路由(导航菜单)数据全部存储在后台
  2. 路由数据配置在前端,后台只存储权限信息

注意:本文通过Mock模拟后端接口

方式1:路由(导航菜单)数据全部存储在后台

定义路由数据结构体,在文件中:src/mock/data.js

export const routersData = [{
   path: '/pet',//访问路径
   name: 'Pet',//路由的名字,这个与i18n有关,需要唯一
   meta: {
    title: '宠物',//标题
    hideInMenu: false,//是否在左侧导航菜单隐藏
    icon: 'logo-freebsd-devil'//图标
   },
   component: 'components/main',//组件文件路径,不需要Import
   children: [{//嵌套路由
    path: 'cat',
    name: 'Cat',
    meta: {
     title: '猫咪',
     hideInMenu: false,
     icon: 'ios-cloudy-night'
    },
    component: 'view/pet/cat/Cat.vue'
   }, {
    path: 'dog',
    name: 'Dog',
    meta: {
     hideInMenu: false,
     title: '狗娃',
     icon: 'ios-color-filter'
    },
    component: 'view/pet/dog/Dog.vue'
   }, {
    path: 'pig',
    name: 'Pig',
    meta: {
     hideInMenu: false,
     title: '猪啊',
     icon: 'ios-contact'
    },
    component: 'view/pet/pig/Pig.vue',
    children: [
     {
      path: 'female',
      name: 'Female',
      meta: {
       hideInMenu: false,
       title: '母猪',
       icon: 'ios-contact'
      },
      component: 'view/pet/pig/Pig.vue',
     },
     {
      path: 'male',
      name: 'Male',
      meta: {
       hideInMenu: false,
       title: '公猪',
       icon: 'ios-contact'
      },
      component: 'view/pet/pig/Pig.vue',
     }
    ]
   }]}]

暴露ajax调用接口:src/mock/index.js,中增加:

Mock.mock(/\/sys\/routers/, routersData)

实现一个ajax调用:src/api/routers.js中增加:

export const getRouterReq = (access) => {
   return axios.request({
    url: '/sys/routers',
    params: {
     access
    },
    method: 'get'
 })}

1、在store中定义动态路由相关逻辑,修改:src/store/module/app.js

引入ajax请求:

import {getRouterReq} from '@/api/routers'

定义两个state,如下

state: {
  .....
  routers: [],//拿到的路由数据
  hasGetRouter: false//是否已经拿过路由数据
 },

同步增加mutations:

mutations:{
   ......
   //设置路由数据
  setRouters(state, routers) {
   state.routers = routers
  },
  //设置是否已经拿过路由
  setHasGetRouter(state, status) {
   state.hasGetRouter = status
  }......}

增加一个action:

action:{
........
  getRouters({commit}) {
   return new Promise((resolve, reject) => {
    try {
     getRouterReq().then(res => {
      let routers = backendMenusToRouters(res.data)
      commit('setRouters', routers)
      commit('setHasGetRouter', true)
      resolve(routers)
     }).catch(err => {
      reject(err)
     })
    } catch (error) {
     reject(error)
    }
   })
  },
  ........
}

此处用到了一个函数:backendMenusToRouters,这个函数定义在src/libs/util.js中,用来对后端返回的路由数据递归处理,行程vue的路由。

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
}

修改src/router/index.js,增加动态路由加入逻辑,主要方法:

const initRouters = (store) => {
 //这个人登录了已经
 if (store.state.user.hasGetInfo) {
  //路由加载过了
  if (store.state.app.hasGetRouter && store.state.app.routers && store.state.app.routers.length > 0) {
   console.log("已经加载过了路由")
  } else {
   //加载路由
   console.log("开始加载路由权限...")
   store.dispatch('getUserMenus').then(routers => {
    //此处routers已经是按照权限过滤后的路由了,没权限的,不加入路由,无法访问
    //路由重置一下把404放最后
    const newRouter = new Router({
     routes,
     mode: config.routerModel
    })
    router.matcher = newRouter.matcher;
    //把404加最后面,如果用router.push({name:'xxxx'})这种的话,404页面可能空白,用path:'/aa/bb'
    router.addRoutes(routers.concat([{
     path: '*',
     name: 'error_404',
     meta: {
      hideInMenu: true
     },
     component: () => import(/* webpackChunkName: "404" */'@/view/error-page/404.vue')
    }]))
   }).finally(() => {
   })
  }
 }}

每次路由加载之前,都会判断是否已经初始化过系统路由,如果没有,则初始化。

至此,动态路由基本实现。文章可能有遗漏和不足,欢迎探讨。第二种实现方式

具体实现,请参见: https://github.com/MayBeWrong/iview-admin-dynamic-router

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript脚本性能优化注意事项
Nov 18 Javascript
js setattribute批量设置css样式
Nov 26 Javascript
Dom与浏览器兼容性说明
Oct 25 Javascript
JavaScript中使用构造器创建对象无需new的情况说明
Mar 01 Javascript
获取JS中网页各种高宽与位置的方法总结
Jul 27 Javascript
AngularJS Bootstrap详细介绍及实例代码
Jul 28 Javascript
xmlplus组件设计系列之选项卡(Tabbar)(5)
May 03 Javascript
如何使node也支持从url加载一个module详解
Jun 05 Javascript
javascript中UMD规范的代码推演
Aug 29 Javascript
react配置antd按需加载的使用
Feb 11 Javascript
jsonp格式前端发送和后台接受写法的代码详解
Nov 07 Javascript
如何实现echarts markline标签名显示自己想要的
Jul 20 Javascript
你不可不知的Vue.js列表渲染详解
Oct 01 #Javascript
基于VUE的v-charts的曲线显示功能
Oct 01 #Javascript
Echarts地图添加引导线效果(labelLine)
Sep 30 #Javascript
javascript实现摄像头拍照预览
Sep 30 #Javascript
java和js实现的洗牌小程序
Sep 30 #Javascript
JS使用H5实现图片预览功能
Sep 30 #Javascript
在vue中使用jsx语法的使用方法
Sep 30 #Javascript
You might like
php读取csv文件并输出的方法
2015/03/14 PHP
php解析xml方法实例详解
2015/05/12 PHP
javascript add event remove event
2008/04/07 Javascript
JQuery优缺点分析说明
2010/06/09 Javascript
JavaScript编程开发中的五个实用小技巧
2010/07/22 Javascript
jquery.post用法关于type设置问题补充
2014/01/03 Javascript
JavaScript中判断整数的多种方法总结
2014/11/08 Javascript
Bootstrap 最常用的JS插件系列总结(图片轮播、标签切换等)
2016/07/14 Javascript
使用contextMenu插件实现Bootstrap table弹出右键菜单
2017/02/20 Javascript
jQuery实现表格冻结顶栏效果
2017/08/20 jQuery
linux 后台运行node服务指令方法
2018/05/23 Javascript
vue2 设置router-view默认路径的实例
2018/09/20 Javascript
Vue组件生命周期运行原理解析
2020/11/25 Vue.js
[00:43]FTP典藏礼包 DOTA2三大英雄霸气新套装
2014/03/21 DOTA
[03:37]2016完美“圣”典 风云人物:Mikasa专访
2016/12/07 DOTA
[02:18]《我与DAC》之工作人员:为了热爱DOTA2的玩家们
2018/03/28 DOTA
python如何通过protobuf实现rpc
2016/03/06 Python
Python读取一个目录下所有目录和文件的方法
2016/07/15 Python
python一键升级所有pip package的方法
2017/01/16 Python
Python实现的弹球小游戏示例
2017/08/01 Python
python中返回矩阵的行列方法
2018/04/04 Python
Django框架模板注入操作示例【变量传递到模板】
2018/12/19 Python
python将txt文件读取为字典的示例
2018/12/22 Python
Python3 pandas 操作列表实例详解
2019/09/23 Python
python selenium自动化测试框架搭建的方法步骤
2020/06/14 Python
浅谈django 模型类使用save()方法的好处与注意事项
2020/03/28 Python
Keras官方中文文档:性能评估Metrices详解
2020/06/15 Python
澳大利亚香水在线:Price Rite Mart
2017/12/28 全球购物
StubHub中国:购买和出售全球活动门票
2020/01/01 全球购物
初中生自我鉴定
2014/02/04 职场文书
庆祝三八妇女节标语
2014/10/09 职场文书
晶体管来复再生式二管收音机
2021/04/22 无线电
JavaScript使用canvas绘制坐标和线
2021/04/28 Javascript
CSS实现隐藏搜索框功能(动画正反向序列)
2021/07/21 HTML / CSS
JavaScript中MutationObServer监听DOM元素详情
2021/11/27 Javascript
Win10本地连接不见了怎么恢复? win10系统电脑本地连接不见了解决方法
2023/01/09 数码科技