基于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 相关文章推荐
List the Codec Files on a Computer
Jun 18 Javascript
不用写JS也能使用EXTJS视频演示
Dec 29 Javascript
js实现的日期操作类DateTime函数代码
Mar 16 Javascript
分享精心挑选的12款优秀jQuery Ajax分页插件和教程
Aug 09 Javascript
Backbone.js中的集合详解
Jan 14 Javascript
jQuery插件实现控制网页元素动态居中显示
Mar 24 Javascript
js中数组插入、删除元素操作的方法
Feb 15 Javascript
详解javascript对数组和json数组的操作
Apr 15 Javascript
Flutter实现仿微信底部菜单栏功能
Sep 18 Javascript
vue-cli 为项目设置别名的方法
Oct 15 Javascript
Javascript幻灯片播放功能实现过程解析
May 07 Javascript
jQuery--遍历操作实例小结【后代、同胞及过滤】
May 22 jQuery
你不可不知的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
用session做客户验证时的注意事项
2006/10/09 PHP
PHP实现发送邮件的方法(基于简单邮件发送类)
2015/12/17 PHP
PHP 断点续传实例详解
2017/11/11 PHP
Ajax+PHP实现的模拟进度条功能示例
2019/02/11 PHP
php探针不显示内存解决方法
2019/09/17 PHP
ThinkPHP5 框架引入 Go AOP,PHP AOP编程项目详解
2020/05/12 PHP
JavaScript 解析读取XML文档 实例代码
2009/07/07 Javascript
javascript:json数据的页面绑定示例代码
2014/01/26 Javascript
JS设置获取cookies的方法
2014/01/26 Javascript
jquery中添加属性和删除属性
2015/06/03 Javascript
实例讲解js验证表单项是否为空的方法
2016/01/09 Javascript
微信小程序前端源码逻辑和工作流
2016/09/25 Javascript
JSON中key动态设置及JSON.parse和JSON.stringify()的区别
2016/12/29 Javascript
教你用十行node.js代码读取docx的文本
2017/03/08 Javascript
jQuery封装animate.css的实例
2018/01/04 jQuery
详解微信小程序canvas圆角矩形的绘制的方法
2018/08/22 Javascript
python计算牛顿迭代多项式实例分析
2015/05/07 Python
django 解决manage.py migrate无效的问题
2018/05/27 Python
python中scikit-learn机器代码实例
2018/08/05 Python
Pycharm之快速定位到某行快捷键的方法
2019/01/20 Python
pyqt5利用pyqtDesigner实现登录界面
2019/03/28 Python
python3中rank函数的用法
2019/11/27 Python
Python面向对象中类(class)的简单理解与用法分析
2020/02/21 Python
Django-migrate报错问题解决方案
2020/04/21 Python
Django crontab定时任务模块操作方法解析
2020/09/10 Python
心理学专业大学生职业生涯规划范文
2014/02/19 职场文书
个人工作主要事迹
2014/05/08 职场文书
2014年乡镇领导个人整改措施
2014/09/19 职场文书
四风个人对照检查材料思想汇报(办公室通用版)
2014/10/07 职场文书
2015元旦晚会主持人开场白+结束语
2014/12/14 职场文书
同意离婚答辩状
2015/05/22 职场文书
致三级跳运动员加油稿
2015/07/21 职场文书
个人工作失误的保证书怎么写?
2019/06/21 职场文书
解决Goland 同一个package中函数互相调用的问题
2021/05/06 Golang
SQL 窗口函数实现高效分页查询的案例分析
2021/05/21 SQL Server
用Python仅20行代码编写一个简单的端口扫描器
2022/04/08 Python