怎样使用vueaddRoutes实现动态权限路由菜单

阅读:

这次给大家带来怎样使用vue addRoutes实现动态权限路由菜单,怎样使用vue addRoutes实现动态权限路由菜单的注意事项有哪些,下面就是实战案例,一起来看一下。

vue点击左侧菜单右侧显示内容 vue有上菜单也有左侧菜单vue点击左侧菜单右侧显示内容 vue有上菜单也有左侧菜单


vue点击左侧菜单右侧显示内容 vue有上菜单也有左侧菜单


vue点击左侧菜单右侧显示内容 vue有上菜单也有左侧菜单


需求

近接手一个后台管理系统,需要实现导航菜单从后台拉取的效果;根据登录用户的权限不同分别拉出来的导航菜单也不一样,另外可作的界面也存在区别。

问题

因为后台管理系统是准备使用vue+vue-router+element-ui+vuex的搭配来做的,可是单页应用在进入页面之前就已经将vue-router实例化并且注入vue实例中了,所以在进入登录页面的时候旧没办法在重新定制路由了。接下来各种百之谷之,发现vue-router在2.0版本中提供了addRoutes方法添加路由,希望的曙光出现。

经过一番折腾终于实现了功能,记录下来便于回顾,也希望能帮助到同样有需求的同志。

思路

1、首先在本地配置好固定不变的路由地址,例如登录,404这些页面,如下:

import Vue from 'vue'

import Router from 'vue-router'

import store from '@/vuex/store'

Vue.use(Router)

routes: [

{path: '/login',

name: 'login',

meta: {requireAuth: false},

// 模块使用异步加载

component: (resolve) => require(['../components/login/login.vue'], resolve)

}]

})

// 拦截登录,token验证

router.beforeEach((to, from, next) => {

if === undefined) {

if (store.state.token) {

next()

} else {

next({

path: '/login'

})

}} else {

next()

}})

export default router配置好这些固定的路由后我们才能够到登录页面,不然是无法继续下去的。

2、然后重要的一步,我们需要跟后端老铁约定好需要返回的权限菜单列表信息;首先这里我们先分析一下自己需要的路由结构,这里以我自己的路由作为例子。如果是我自己直接定义路由的话,会是以下结构:

routes: [

{path: '/login',

name: 'login',

meta: {requireAuth: false},

component: (resolve) => require(['../components/login/login.vue'], resolve)

},

{path: '/',

redirect: '/layout'

},

component: (resolve) => require(['../layout.vue'], resolve),

children: [

{path: 'index',

meta: {

type: '1', //控制是否显示隐藏 1显示,2隐藏

code: 00010001, // 后面需要控制路由高亮

title: '首页', // 菜单名称

permissonList: [] // 权限列表

},

{...

}]

}]

})根据以上结构分析,其实真正需要动态配置的路由其实是/layout下面的children部分,所以需要后端返回给我们包含所有路由的一个数组就可以了

返回的数据中rootList中是一级导航的列表,一级导航实际是没有路由功能,只是作为切换二级菜单的触发器,subList才是我们真正需要的路由信息。

3、拿到权限路由信息后,需要我们在本地对数据进行处理组装成我们需要的数据:

// 登录

login () {

let params = {

account: this.loginForm.username,

password: encrypt(this.loginForm.password)

this.$.t(this.$bumng + '/login', this.$HP(params))

.then((res) => {

this.loging = false

console.('菜单列表:', res)

if (res.resultCode === this.$state_ok) {

// 合并一级菜单和二级菜单,便于显示

let menus = res.subList)

this.seRes({label: 'menuList', value: menus})

// 根据subList处理路由

let routes = 本地化subList,便于在刷新页面的时候重新配置路由

this.seRes({label: 'subList', value: res.subList})

// 防止重复配置相同路由

if (this.$router.options.routes.length <= 1) {

this.$router.addRoutes(routes)

// this.$router不是响应式的,所以手动将路由元注入路由对象

this.$router.options.routes.push(routes)

}})

.catch((err) => {

this.loging = false

console.e}this.$router.replace('/layout/index')rror('错误:', err)

})

},处理菜单列表和subList的方法:mergeSubInRoot 和 mergeRoutes

const routes = [

{path: '/',

redirect: '/layout'

},

component: (resolve) => require(['../layout.vue'], resolve),

children: []

}]

/

合并主菜单和子菜单

@param: rootList [Array] 主菜单列表

@param: subList [Array] 子菜单

/

mergeSubInRoot (roots, subs) {

if (roots && subs) {

for (let i = 0; i < roots.length; i++) {

let rootCode = roots[i].code

roots[i].children = []

for (let j = 0; j < subs.length; j++) {

if (rootCode === subs[j].code.substring(0, 4)) {

roots[i].children.push(subs[j])

return roots

},

/

合并远程路由到本地路由

@param: routes [Array] 本地路由列表

/

if (subs) {

for (let i = 0; i < subs.length; i++) {

let temp = {

path: subs[i].actUrl,

name: subs[i].actUrl,

component: (resolve) => require([`@/components/${subs[i]ponent}.vue`], resolve),

meta: {

type: subs[i].type,

code: subs[i].code,

permissionList: subs[i].permissionList

routes[1].children.push(temp)

return routes

}}至此我们已经将权限路由成功配置进本地路由了,我的系统登录进入如下

后续优化

1、菜单列表的显示以及二级导航切换:

mode="horizontal"

:default-active="activeCode"

background-color="#545c64"

text-color="#fff"

active-text-color="#ffd04b">

{{.name}}

2、防止刷新路由丢失;由于在刷新的时候单页应用会重新初始化,这时候所有配置的路由都会丢失,一朝回到,只有本地配置的路由能够跳转。这时候我们可以在app.vue(ps:不论在哪里进行刷新,app.vue都会执行)中执行如下代码:

import {decrypt} from '@/libs/AES'

import handleMenu from '@/router/handleMenu'

name: 'app',

created () {

// 当this.$router.options.routes的长度为1,且本地缓存存在菜单列表的时候才重新配置路由

if (this.$router.options.routes.length <= 1 && sessionStorage.getItem('subList')) {

let subList = JSON.parse(decrypt(sessionStorage.getItem('subList')))

let routes = this.$router不是响应式的,所以手动将路由元注入路由对象

this.$router.options.routes.push(routes)

}这样即使刷新,也会重新配置路由了。

3、关于页面按钮级别控制,可以自定义一个指令,去做这件事情。因为我们已经权限列表放入了相应路由的meta对象中,所以我们可以很方便的在每个页面回去到当前用户在当前页面所拥有的权限

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

使用create-react-app构建React开发环境步奏详解

如何使用element-ui 限制日期选择

vue-antd-admin框架(二) 布局与页面渲染