基于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继承 笔记
Jul 13 Javascript
jQuery插件 selectToSelect使用方法
Oct 02 Javascript
javascript实现表单验证
Jan 29 Javascript
JS中多种方式创建对象详解
Mar 22 Javascript
jQuery基于扩展简单实现倒计时功能的方法
May 14 Javascript
Bootstrap3制作搜索框样式的方法
Jul 11 Javascript
JS字符串长度判断,超出进行自动截取的实例(支持中文)
Mar 06 Javascript
Node.js创建Web、TCP服务器
Dec 05 Javascript
解决layer弹出层自适应页面大小的问题
Sep 16 Javascript
微信小程序获取地理位置及经纬度授权代码实例
Sep 18 Javascript
JavaScript如何处理移动端拍摄图片旋转问题
Nov 16 Javascript
vue 实现弹窗关闭后刷新效果
Apr 08 Vue.js
你不可不知的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
基于curl数据采集之单页面采集函数get_html的使用
2013/04/28 PHP
php object转数组示例
2014/01/15 PHP
thinkphp3查询mssql数据库乱码解决方法分享
2014/02/11 PHP
php通过递归方式复制目录和子目录的方法
2015/03/13 PHP
Yii使用migrate命令执行sql语句的方法
2016/03/15 PHP
php+Memcached实现简单留言板功能示例
2017/02/15 PHP
ThinkPHP实现生成和校验验证码功能
2017/04/28 PHP
如何在PHP中读写文件
2020/09/07 PHP
MooTools 1.2介绍
2009/09/14 Javascript
JavaScript经典效果集锦
2010/07/06 Javascript
JS 无限级 Select效果实现代码(json格式)
2011/08/30 Javascript
原生javascript实现无间缝滚动示例
2014/01/28 Javascript
微信小程序开发图片拖拽实例详解
2017/05/05 Javascript
bootstrapvalidator之API学习教程
2017/06/29 Javascript
vue+jquery+lodash实现滑动时顶部悬浮固定效果
2018/04/28 jQuery
基于ionic实现下拉刷新功能
2018/05/10 Javascript
vue移动端实现红包雨效果
2020/06/23 Javascript
express+vue+mongodb+session 实现注册登录功能
2018/12/06 Javascript
jquery实现下载图片功能
2019/07/18 jQuery
python文件操作之目录遍历实例分析
2015/05/20 Python
python3 与python2 异常处理的区别与联系
2016/06/19 Python
Python pandas常用函数详解
2018/02/07 Python
python使用matplotlib模块绘制多条折线图、散点图
2020/04/26 Python
解决Python下json.loads()中文字符出错的问题
2018/12/19 Python
Python元组 tuple的概念与基本操作详解【定义、创建、访问、计数、推导式等】
2019/10/30 Python
Python+PyQt5实现灭霸响指功能
2020/05/25 Python
Python+Opencv身份证号码区域提取及识别实现
2020/08/25 Python
Django静态文件加载失败解决方案
2020/08/26 Python
HTML5之语义标签介绍
2016/07/07 HTML / CSS
美国皮靴公司自1863年:The Frye Company
2016/11/30 全球购物
美国滑雪板和装备购物网站:Skis.com
2018/12/20 全球购物
模范家庭事迹材料
2014/02/10 职场文书
管理部副部长岗位职责范文
2014/03/09 职场文书
乐观自信演讲稿范文
2014/05/21 职场文书
民事诉讼代理授权委托书范本
2014/10/08 职场文书
2016幼儿教师自荐信范文
2016/01/28 职场文书