基于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 相关文章推荐
jQuery中的常用事件总结
Dec 27 Javascript
jquery弹窗插件colorbox绑定动态生成元素的方法
Jun 20 Javascript
bootstrap改变按钮加载状态
Dec 01 Javascript
JQuery boxy插件在IE中边角图片不显示问题的解决
May 20 Javascript
JavaScript中获取Radio被选中的值
Nov 11 Javascript
BootStrap的JS插件之轮播效果案例详解
May 16 Javascript
基于原生JS实现图片裁剪
Aug 01 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
Oct 10 Javascript
JS实现加载时锁定HTML页面元素的方法
Jun 24 Javascript
node+koa2+mysql+bootstrap搭建一个前端论坛
May 06 Javascript
微信小程序image图片加载完成监听
Aug 31 Javascript
es6中Promise 对象基本功能与用法实例分析
Feb 23 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
2019十大人气国漫
2020/03/13 国漫
解析coreseek for sphinx的使用
2013/06/21 PHP
php实现MD5加密16位(不要默认的32位)
2013/08/12 PHP
php文件包含目录配置open_basedir的使用与性能详解
2017/04/03 PHP
window.location和document.location的区别分析
2008/12/23 Javascript
jQuery版仿Path菜单效果
2011/12/15 Javascript
js/jQuery对象互转(快速操作dom元素)
2013/02/04 Javascript
JQuery异步加载无限下拉框级联功能实现示例
2014/02/19 Javascript
JavaScript设计模式之单件模式介绍
2014/12/28 Javascript
js实现新年倒计时效果
2015/12/10 Javascript
Node.js的MongoDB驱动Mongoose基本使用教程
2016/03/01 Javascript
微信小程序 教程之数据绑定
2016/10/18 Javascript
JavaScript实现审核流程状态的动态显示进度条
2017/03/15 Javascript
javascript实现的图片预览功能
2017/03/25 Javascript
JS优化与惰性载入函数实例分析
2017/04/06 Javascript
vue-cli webpack模板项目搭建及打包时路径问题的解决方法
2018/02/26 Javascript
JavaScript图片处理与合成总结
2018/03/04 Javascript
vue 地区选择器v-distpicker的常用功能
2019/07/23 Javascript
vue 实现超长文本截取,悬浮框提示
2020/07/29 Javascript
[05:09]DOTA2-DPC中国联赛2月22日Recap集锦
2021/03/11 DOTA
利用Fn.py库在Python中进行函数式编程
2015/04/22 Python
Python基础入门之seed()方法的使用
2015/05/15 Python
python如何实现远程控制电脑(结合微信)
2015/12/21 Python
Python基于dom操作xml数据的方法示例
2018/05/12 Python
解决PyCharm的Python.exe已经停止工作的问题
2018/11/29 Python
python如何以表格形式打印输出的方法示例
2019/06/21 Python
python 合并多个excel中同名的sheet
2021/01/22 Python
优秀学生自我鉴定范例
2013/12/18 职场文书
特教教师先进事迹
2014/05/21 职场文书
镇人大副主席民主生活会对照检查材料思想汇报
2014/10/01 职场文书
党员评议思想汇报
2014/10/08 职场文书
买房协议书范本
2014/10/23 职场文书
业务员辞职信范文
2015/03/02 职场文书
转学证明范本
2015/06/19 职场文书
Html5调用企业微信的实现
2021/04/16 HTML / CSS
python文件与路径操作神器 pathlib
2022/04/01 Python