基于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的Pager分页器实现代码
Jul 17 Javascript
jquery live()调用不存在的解决方法
Feb 26 Javascript
深入学习jQuery Validate表单验证(二)
Jan 18 Javascript
vue,angular,avalon这三种MVVM框架优缺点
Apr 27 Javascript
Bootstrap3制作搜索框样式的方法
Jul 11 Javascript
JSON与String互转的实现方法(Javascript)
Sep 27 Javascript
原生js实现图片放大缩小计时器效果
Jan 20 Javascript
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
Feb 13 Javascript
jQuery插件HighCharts绘制2D圆环图效果示例【附demo源码下载】
Mar 09 Javascript
JavaScript通过filereader接口读取文件
May 10 Javascript
vue 本地服务不能被外部IP访问的完美解决方法
Oct 29 Javascript
解决vuex数据异步造成初始化的时候没值报错问题
Nov 13 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
phpmyadmin导入(import)文件限制的解决办法
2009/12/11 PHP
php 深入理解strtotime函数的使用详解
2013/05/23 PHP
PHP调用C#开发的dll类库方法
2014/07/28 PHP
Laravel框架中扩展函数、扩展自定义类的方法
2014/09/04 PHP
PHP下SSL加密解密、验证、签名方法(很简单)
2020/06/28 PHP
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
2016/01/07 PHP
js直接编辑当前cookie的脚本
2008/09/14 Javascript
JavaScript 应用技巧集合[推荐]
2009/08/30 Javascript
JS判断是否为数字,是否为整数,是否为浮点数的代码
2010/04/24 Javascript
js统计录入文本框中字符的个数并加以限制不超过多少
2014/05/23 Javascript
JS基于FileSystemObject创建一个指定路径的TXT文本文件
2015/08/05 Javascript
JavaScript的代码编写格式规范指南
2015/12/07 Javascript
javascript原型继承工作原理和实例详解
2016/04/07 Javascript
javascript解决小数的加减乘除精度丢失的方案
2016/05/31 Javascript
vue.js实现仿原生ios时间选择组件实例代码
2016/12/21 Javascript
详解Vuejs2.0之异步跨域请求
2017/04/20 Javascript
微信小程序“摇一摇”的实例代码
2017/07/20 Javascript
利用node.js+mongodb如何搭建一个简单登录注册的功能详解
2017/07/30 Javascript
NodeJS模块与ES6模块系统语法及注意点详解
2019/01/04 NodeJs
vue的hash值原理也是table切换实例代码
2020/12/14 Vue.js
[46:16]2018DOTA2亚洲邀请赛3月30日 小组赛B组 iG VS VP
2018/03/31 DOTA
python自定义类并使用的方法
2015/05/07 Python
pandas DataFrame 根据多列的值做判断,生成新的列值实例
2018/05/18 Python
Python读取系统文件夹内所有文件并统计数量的方法
2018/10/23 Python
Python使用sys.exc_info()方法获取异常信息
2020/07/23 Python
Django中ORM的基本使用教程
2020/12/22 Python
CSS3 please 跨浏览器的CSS3产生器
2010/03/14 HTML / CSS
Gweniss格温妮丝女包官网:英国纯手工制造潮流包包品牌
2018/02/07 全球购物
Carter’s OshKosh加拿大:购买婴幼儿服装和童装
2018/11/27 全球购物
技校生自我鉴定范文
2013/09/26 职场文书
婚礼新郎父母答谢词
2014/01/16 职场文书
工商治理实习生的自我评价分享
2014/02/20 职场文书
《窗前的气球》教学反思
2014/04/07 职场文书
寒山寺导游词
2015/02/03 职场文书
农村房屋租赁合同(范本)
2019/07/23 职场文书
Mysql将字符串按照指定字符分割的正确方法
2022/05/30 MySQL