基于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的onchange事件与jQuery的change()方法比较
Sep 28 Javascript
js中top/parent/frame概述及案例应用
Feb 06 Javascript
IE关闭时判断及AJAX注销案例学习
Feb 18 Javascript
javascript实现获取服务器时间
May 19 Javascript
JavaScript评论点赞功能的实现方法
Mar 13 Javascript
微信小程序的日期选择器的实例详解
Sep 29 Javascript
详解Vue开发微信H5微信分享签名失败问题解决方案
Aug 09 Javascript
vue组件tabbar使用方法详解
Nov 06 Javascript
微信小程序五子棋游戏的悔棋实现方法【附demo源码下载】
Feb 20 Javascript
TypeScript开发Node.js程序的方法
Apr 30 Javascript
ligerUI的ligerDialog关闭刷新的方法
Sep 27 Javascript
element form 校验数组每一项实例代码
Oct 10 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的面试题集,附我的答案和分析(一)
2006/11/19 PHP
PHP 程序员的调试技术小结
2009/11/15 PHP
利用yahoo汇率接口实现实时汇率转换示例 汇率转换器
2014/01/14 PHP
php实现根据IP地址获取其所在省市的方法
2015/04/30 PHP
php发送html格式文本邮件的方法
2015/06/10 PHP
thinkphp验证码的实现(form、ajax实现验证)
2016/07/28 PHP
浏览器脚本兼容 文本框中,回车键触发事件的兼容
2010/06/21 Javascript
在jQuery ajax中按钮button和submit的区别分析
2012/10/07 Javascript
NodeJS学习笔记之网络编程
2014/08/03 NodeJs
jQuery插件Tmpl的简单使用方法
2015/04/27 Javascript
javascript html5移动端轻松实现文件上传
2020/03/27 Javascript
关于cookie的初识和运用(js和jq)
2016/04/07 Javascript
jQuery validate验证插件使用详解
2016/05/11 Javascript
使用bootstrap typeahead插件实现输入框自动补全之问题及解决办法
2016/07/07 Javascript
详解Javascript中的原型OOP
2016/10/12 Javascript
JavaScript ES6中CLASS的使用详解
2016/11/22 Javascript
Angular-Touch库用法示例
2016/12/22 Javascript
jquery实现图片上传前本地预览
2017/04/28 jQuery
JavaScript实现图片无缝滚动效果
2017/07/07 Javascript
Javascript防止图片拉伸的自适应处理方法
2017/12/26 Javascript
jquery实现选项卡切换代码实例
2019/05/14 jQuery
使用django-guardian实现django-admin的行级权限控制的方法
2018/10/30 Python
Python OpenCV调用摄像头检测人脸并截图
2020/08/20 Python
用python wxpy管理微信公众号并利用微信获取自己的开源数据
2019/07/30 Python
在pandas中遍历DataFrame行的实现方法
2019/10/23 Python
Pytorch GPU显存充足却显示out of memory的解决方式
2020/01/13 Python
通过Python扫描代码关键字并进行预警的实现方法
2020/05/24 Python
python下载的库包存放路径
2020/07/27 Python
快速创建python 虚拟环境
2020/11/28 Python
万得城电器土耳其网站:欧洲第一大电子产品零售商
2016/10/07 全球购物
Yahoo-PHP面试题3
2012/01/14 面试题
英语专业推荐信
2013/11/16 职场文书
新党章心得体会
2014/09/04 职场文书
2014年采购工作总结
2014/11/20 职场文书
2014年结对帮扶工作总结
2014/12/17 职场文书
展览会邀请函
2015/02/02 职场文书