基于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 相关文章推荐
学习js所必须要知道的一些
Mar 07 Javascript
jQuery中$.fn的用法示例介绍
Nov 05 Javascript
JS对象转换为Jquery对象实现代码
Dec 29 Javascript
jquery为页面增加快捷键示例
Jan 31 Javascript
JS动态加载当前时间的方法
Feb 09 Javascript
js实现按钮控制图片360度翻转特效的方法
Feb 17 Javascript
在AngularJS应用中实现一些动画效果的代码
Jun 18 Javascript
javacript replace 正则取字符串中的值并替换【推荐】
Sep 13 Javascript
解决angularjs service中依赖注入$scope报错的问题
Oct 02 Javascript
vue.js实现备忘录demo
Jun 26 Javascript
解决layer.prompt无效的问题
Sep 24 Javascript
解决Vue动态加载本地图片问题
Oct 09 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中使用gettext来支持多语言的方法
2011/05/02 PHP
php技术实现加载字体并保存成图片
2015/07/27 PHP
PHP常用正则表达式精选(推荐)
2019/05/28 PHP
根据分辨率不同,调用不同的css文件
2006/08/25 Javascript
location.href用法总结(最主要的)
2013/12/27 Javascript
玩转方法:call和apply
2014/05/08 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
2015/10/02 Javascript
jQuery简单实现MD5加密的方法
2017/03/03 Javascript
Vue2.0父子组件传递函数的教程详解
2017/10/16 Javascript
vue的过滤器filter实例详解
2018/09/17 Javascript
Vue面试题及Vue知识点整理
2018/10/07 Javascript
Vue 样式绑定的实现方法
2019/01/15 Javascript
Vue使用Proxy监听所有接口状态的方法实现
2019/06/07 Javascript
Node.js系列之连接DB的方法(3)
2019/08/30 Javascript
layer.alert回调函数执行关闭弹窗的实例
2019/09/11 Javascript
eslint+prettier统一代码风格的实现方法
2020/07/22 Javascript
Js图片点击切换轮播实现代码
2020/07/27 Javascript
JavaScript用document.write()输出换行的示例代码
2020/11/26 Javascript
Windows系统下安装Python的SSH模块教程
2015/02/05 Python
浅谈django model的get和filter方法的区别(必看篇)
2017/05/23 Python
Python实现读写INI配置文件的方法示例
2018/06/09 Python
对Pytorch神经网络初始化kaiming分布详解
2019/08/18 Python
解决Python import .pyd 可能遇到路径的问题
2021/03/04 Python
阿迪达斯加拿大官网:Adidas加拿大
2016/08/25 全球购物
世界最大的票务市场:viagogo
2017/02/16 全球购物
Omio美国:全欧洲低价大巴、火车和航班搜索和比价
2017/11/08 全球购物
加拿大国民体育购物网站:National Sports
2018/11/04 全球购物
阿迪达斯印尼官方网站:adidas印尼
2020/02/10 全球购物
书法培训心得体会
2014/01/05 职场文书
2014年党务公开实施方案
2014/02/27 职场文书
班级活动总结格式
2014/08/30 职场文书
教师群众路线心得体会
2014/11/04 职场文书
2015年导购员工作总结
2015/04/25 职场文书
golang 实用库gotable的具体使用
2021/07/01 Golang
动画「进击的巨人」第86话播出感谢绘公开
2022/03/21 日漫
多人盗宝《绿林侠盗》第三赛季4.5上线 跨平台实装
2022/04/03 其他游戏