基于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增删元素的代码
Feb 14 Javascript
js自动生成对象的属性示例代码
Oct 28 Javascript
javascript避免数字计算精度误差的方法详解
Mar 05 Javascript
Angular.js中angular-ui-router的简单实践
Jul 18 Javascript
bootstrap3中container与container_fluid外层容器的区别讲解
Dec 04 Javascript
Koa项目搭建过程详细记录
Apr 12 Javascript
vue better scroll 无法滚动的解决方法
Jun 07 Javascript
jQuery点击页面其他部分隐藏下拉菜单功能
Nov 27 jQuery
如何通过setTimeout理解JS运行机制详解
Mar 23 Javascript
Vue 动态添加路由及生成菜单的方法示例
Jun 20 Javascript
JavaScript动态生成表格的示例
Nov 02 Javascript
抖音短视频(douyin)去水印工具的实现代码
Mar 30 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截取后台登陆密码的代码
2012/05/05 PHP
微信开发之网页授权获取用户信息(二)
2016/01/08 PHP
PHP迭代器和迭代的实现与使用方法分析
2018/04/19 PHP
PHP多维数组指定多字段排序的示例代码
2018/05/16 PHP
Laravel 5.2 文档 数据库 ―― 起步介绍
2019/10/21 PHP
JQuery扩展插件Validate 1 基本使用方法并打包下载
2011/09/05 Javascript
通过JavaScript使Div居中并随网页大小改变而改变
2013/06/24 Javascript
各种页面定时跳转(倒计时跳转)代码总结
2013/10/24 Javascript
使用javascript实现ListBox左右全选,单选,多选,全请
2013/11/07 Javascript
多选列表框动态添加,移动,删除,全选等操作的简单实例
2014/01/13 Javascript
javascript的数组和常用函数详解
2014/05/09 Javascript
JavaScrip调试技巧之断点调试
2015/10/22 Javascript
Jquery uploadify上传插件使用详解
2016/01/13 Javascript
利用vue实现模态框组件
2016/12/19 Javascript
初探js和简单隐藏效果的实例
2017/11/23 Javascript
手把手教你vue-cli单页到多页应用的方法
2018/05/31 Javascript
让Vue响应Map或Set的变化操作
2020/11/11 Javascript
Python计算一个文件里字数的方法
2015/06/15 Python
对Python2与Python3中__bool__方法的差异详解
2018/11/01 Python
python实现程序重启和系统重启方式
2020/04/16 Python
解决Jupyter notebook中.py与.ipynb文件的import问题
2020/04/21 Python
HTML5 FileReader对象的具体使用方法
2020/05/22 HTML / CSS
屈臣氏乌克兰:Watsons UA
2019/10/29 全球购物
印度领先的眼镜电子商务网站:Lenskart
2019/12/16 全球购物
男女钓鱼靴和甲板鞋:XTRATUF
2021/01/09 全球购物
C语言笔试题
2014/09/04 面试题
Linux如何修改文件和文件夹的权限
2013/09/05 面试题
既然说Ruby中一切都是对象,那么Ruby中类也是对象吗
2013/01/26 面试题
文秘自荐信
2013/10/20 职场文书
竟聘演讲稿范文
2013/12/31 职场文书
端午节活动总结
2014/08/26 职场文书
居委会四风问题个人对照检查材料
2014/09/25 职场文书
暑期社会实践新闻稿
2015/07/17 职场文书
银行培训心得体会范文
2016/01/09 职场文书
《童年的发现》教学反思
2016/02/18 职场文书
公开致歉信
2019/06/24 职场文书