基于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 验证表单(form)中的单选(radio)值
Sep 08 Javascript
一些实用的jQuery代码片段收集
Jul 12 Javascript
css值转换成数值请抛弃parseInt
Oct 24 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
Jan 23 Javascript
iframe异步加载实现点击左边菜单加载右边内容实例讲解
Mar 04 Javascript
深入分析JSONP跨域的原理
Dec 10 Javascript
详解Node.js模块间共享数据库连接的方法
May 24 Javascript
JavaScript蒙板(model)功能的简单实现代码
Aug 04 Javascript
vue.js指令和组件详细介绍及实例
Apr 06 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
Dec 16 jQuery
vue 进阶之实现父子组件间的传值
Apr 26 Javascript
vue前端框架—Mint UI详解(更适用于移动端)
Apr 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的4种常用运行方式详解
2016/12/22 PHP
javascript import css实例代码
2008/07/18 Javascript
ExtJS Window 最小化的一种方法
2009/11/18 Javascript
jquery tab标签页的制作
2010/05/10 Javascript
js操纵跨frame的三级联动select下拉选项实例介绍
2013/05/19 Javascript
js中settimeout方法加参数的使用实例
2014/02/27 Javascript
JavaScript制作的可折叠弹出式菜单示例
2014/04/04 Javascript
jQuery同步提交示例代码
2015/12/12 Javascript
分享Javascript实用方法二
2015/12/13 Javascript
解决微信浏览器Javascript无法使用window.location.reload()刷新页面
2016/06/21 Javascript
JS实现评价的星星功能
2017/08/20 Javascript
Angular 4中如何显示内容的CSS样式示例代码
2017/11/06 Javascript
vue项目优化之通过keep-alive数据缓存的方法
2017/12/11 Javascript
JS基于递归实现网页版计算器的方法分析
2017/12/20 Javascript
Node.js之readline模块的使用详解
2019/03/25 Javascript
每周一练 之 数据结构与算法(Stack)
2019/04/16 Javascript
如何使用proxy实现一个简单完整的MVVM库的示例代码
2019/09/17 Javascript
vue路由传参页面刷新参数丢失问题解决方案
2019/10/08 Javascript
Vue 的双向绑定原理与用法揭秘
2020/05/06 Javascript
python使用cookielib库示例分享
2014/03/03 Python
Python3随机漫步生成数据并绘制
2018/08/27 Python
Python实现高斯函数的三维显示方法
2018/12/29 Python
Python实现数据结构线性链表(单链表)算法示例
2019/05/04 Python
Python符号计算之实现函数极限的方法
2019/07/15 Python
HTML的form表单和django的form表单
2019/07/25 Python
英国儿童设计师服装和玩具购物网站:Zac & Lulu
2020/10/19 全球购物
介绍一下except的用法和作用
2015/01/22 面试题
毕业生医学检验求职信
2013/10/16 职场文书
2013的个人自我评价
2013/12/26 职场文书
快递业务员岗位职责
2014/01/06 职场文书
市三好学生主要事迹
2014/01/28 职场文书
入党自我鉴定
2014/03/25 职场文书
房屋买卖委托书格式范本格式
2014/10/13 职场文书
优秀教师先进材料
2014/12/16 职场文书
五年级作文之学校的四季
2019/12/05 职场文书
pandas中DataFrame数据合并连接(merge、join、concat)
2021/05/30 Python