基于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 相关文章推荐
动态调用CSS文件的JS代码
Jul 29 Javascript
Package.js  现代化的JavaScript项目make工具
May 23 Javascript
jQuery 菜单随滚条改为以定位方式(固定要浏览器顶部)
May 24 Javascript
jQuery操作input值的各种方法总结
Nov 21 Javascript
详解jQuery中的元素的属性和相关操作
Aug 14 Javascript
jQuery向webApi提交post json数据
Jan 16 Javascript
详谈JavaScript的闭包及应用
Jan 17 Javascript
Vue.js常用指令的使用小结
Jun 23 Javascript
javascript编程开发中取色器及封装$函数用法示例
Aug 09 Javascript
node文件批量重命名的方法示例
Oct 23 Javascript
VuePress 快速踩坑小结
Feb 14 Javascript
vue.js路由mode配置之去掉url上默认的#方法
Nov 01 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之规范编程命名小结
2013/05/15 PHP
PHP查找与搜索数组元素方法总结
2015/06/12 PHP
PHP浮点数的一个常见问题
2016/03/10 PHP
WordPress过滤垃圾评论的几种主要方法小结
2016/07/11 PHP
CI(CodeIgniter)框架视图中加载视图的方法
2017/03/24 PHP
JavaScript 密码强度判断代码
2009/09/05 Javascript
javascript中数组的sort()方法的使用介绍
2013/12/18 Javascript
js opener的使用详解
2014/01/11 Javascript
jquery删除指定子元素代码实例
2015/01/13 Javascript
JQuery中上下文选择器实现方法
2015/05/18 Javascript
将form表单通过ajax实现无刷新提交的简单实例
2016/10/12 Javascript
Node.js中的require.resolve方法使用简介
2017/04/23 Javascript
Nodejs搭建wss服务器教程
2017/05/24 NodeJs
angular json对象push到数组中的方法
2018/02/27 Javascript
基于vue-cli vue-router搭建底部导航栏移动前端项目
2018/02/28 Javascript
Node.js+Express+Mysql 实现增删改查
2019/04/03 Javascript
详解如何在Vue项目中发送jsonp请求
2019/10/25 Javascript
Python最基本的输入输出详解
2015/04/25 Python
python处理html转义字符的方法详解
2016/07/01 Python
python 自动化将markdown文件转成html文件的方法
2016/09/23 Python
python中如何使用正则表达式的非贪婪模式示例
2017/10/09 Python
Django1.9 加载通过ImageField上传的图片方法
2018/05/25 Python
python实时监控cpu小工具
2018/06/21 Python
django orm 通过related_name反向查询的方法
2018/12/15 Python
Python pickle模块实现对象序列化
2019/11/22 Python
Django-xadmin+rule对象级权限的实现方式
2020/03/30 Python
若通过ObjectOutputStream向一个文件中多次以追加方式写入object,为什么用ObjectInputStream读取这些object时会产生StreamCorruptedException?
2016/10/17 面试题
园林毕业生自我鉴定范文
2013/12/29 职场文书
幼儿园保育员责任书
2014/07/22 职场文书
机关中层领导干部群众路线教育实践活动个人对照检查材料
2014/09/24 职场文书
助学金感谢信
2015/01/20 职场文书
法律意见书范文
2015/06/04 职场文书
听证会主持词
2015/07/03 职场文书
三好学生竞选稿范文
2019/08/21 职场文书
HTML通过表单实现酒店筛选功能
2021/05/18 HTML / CSS
阿里云服务器部署mongodb的详细过程
2021/09/04 MongoDB