基于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 相关文章推荐
php与js的区别是什么
Aug 05 Javascript
javascript移出节点removeChild()使用介绍
Apr 03 Javascript
浅谈JavaScript中setInterval和setTimeout的使用问题
Aug 01 Javascript
值得分享的轻量级Bootstrap Table表格插件
May 30 Javascript
jQuery控制div实现随滚动条滚动效果
Jun 07 Javascript
微信小程序 css使用技巧总结
Jan 09 Javascript
js实现简易聊天对话框
Aug 17 Javascript
微信小程序表单验证功能完整实例
Dec 01 Javascript
vue二级菜单导航点击选中事件的方法
Sep 12 Javascript
vue.js编译时给生成的文件增加版本号
Sep 17 Javascript
vue quill editor 使用富文本添加上传音频功能
Jan 14 Javascript
解决vue 给window添加和移除resize事件遇到的坑
Jul 21 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中将网址转换为超链接的函数
2011/09/02 PHP
PHP警告Cannot use a scalar value as an array的解决方法
2012/01/11 PHP
PHP版微信小店接口开发实例
2016/11/12 PHP
Yii2配置Nginx伪静态的方法
2017/05/05 PHP
jQuery基本选择器选择元素使用介绍
2013/04/18 Javascript
js点击事件链接的问题解决
2014/04/25 Javascript
jquery禁用右键示例
2014/04/28 Javascript
PHP和NodeJs开发的应用如何共用Session
2015/04/16 NodeJs
JS实现上传图片实时预览功能
2017/05/22 Javascript
javascript定时器取消定时器及优化方法
2017/07/08 Javascript
JavaScript数据类型的存储方法详解
2017/08/25 Javascript
Node Puppeteer图像识别实现百度指数爬虫的示例
2018/02/22 Javascript
vue 利用路由守卫判断是否登录的方法
2018/09/29 Javascript
vscode vue 文件模板的配置方法
2019/07/23 Javascript
小程序如何获取多个formId实现详解
2019/09/20 Javascript
基于js实现复制内容到操作系统粘贴板过程解析
2019/10/11 Javascript
解决vue组件没显示,没起作用,没报错,但该显示的组件没显示问题
2020/09/02 Javascript
jQuery实现计算器功能
2020/10/19 jQuery
[01:10]为家乡而战!完美世界城市挑战赛全国总决赛花絮
2019/07/25 DOTA
Python线程的两种编程方式
2015/04/14 Python
基python实现多线程网页爬虫
2015/09/06 Python
Python基于Pymssql模块实现连接SQL Server数据库的方法详解
2017/07/20 Python
python3实现爬取淘宝美食代码分享
2018/09/23 Python
Python学习笔记之图片人脸检测识别实例教程
2019/03/06 Python
pyqt5 使用cv2 显示图片,摄像头的实例
2019/06/27 Python
python禁用键鼠与提权代码实例
2019/08/16 Python
HTML5新特性 多线程(Worker SharedWorker)
2017/04/24 HTML / CSS
Philosophy美国官网:美国美容品牌
2016/08/15 全球购物
Lime Crime官网:美国一家主打梦幻精灵系的彩妆品牌
2019/03/22 全球购物
如何找出EMP表里面SALARY第N高的employee
2013/12/05 面试题
介绍一下XMLHttpRequest对象
2012/02/12 面试题
大学专科求职信
2014/07/02 职场文书
党员公开承诺书2016
2016/03/24 职场文书
Python基础之tkinter图形化界面学习
2021/04/29 Python
canvas实现贪食蛇的实践
2022/02/15 Javascript
Python创建SQL数据库流程逐步讲解
2022/09/23 Python