vue动态路由实现权限,vue路由动态加载实现权限菜单
这篇文章主要介绍了某视频剪辑软件如何根据权限生成动态路由、导航栏,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
目录
基本思路相关代码
基本思路
1、创建vueRouter,用公共路由实例化
2、创建需要根据权限筛选的路由对象(在路由对象,添加必要的权限判断字段)
3、登录完成,由后端配合返回当前用户的权限集合
4、筛选出有权限的路由对象,利用武鲁特的添加路线方法,生成完整路由
5、处理刷新页面导致武鲁特重新实例化导致路由对象不完善(利用路由器。每个之前导航守卫,利用addRoutes()完善路由对象)
6、侧边导航栏相关代码
相关代码
根据上面的顺序
1、如下
Vue.use(路由器)
//公共路由
export const publicRoutes=[
{
路径:"/",
名称:登录,
组件:登录,
元:{
标题: 登录
}
}
]
//需要根据权限筛选的路由
导出常量异步路由=[
.家,
.设置,
.CRM,
{
路径:"*",
组件:登录,
元:{
隐藏:真
},
重定向:"/"
}
]
常数vr=新路由器({
模式:"历史",
路线:公共路线
})
2、以设置模块为例,角色为判断是的权限字段,角色有这个字段对应的值就有当前页面的权限
从" @/views/layout/layout.vue "导入布局
常量帐户=r=要求。assure([],()=r(require( @/views/seting/account/account。vue’)、‘seting’);
常量日志=r=要求。assure([],()=r(require( @/views/seting/logs/logs。vue’)、‘seting’);
const role=r=require。assure([],()=r(require( @/views/seting/role/role。vue’)、‘seting’);
常量设置=[
{
路径:"/seting ",
组件:布局,
重定向:"/设置/帐户",
元:{
标题: 系统设置,
角色: C6 123号公元前6514年416472年东640年3月f 49297年550年,
图标:"图标-西通"
},
儿童:[
{
路径:"帐户",
名称:账户,
组件:帐户,
元:{
标题: 账号管理,
角色: 1325 cdeb 897 cc 7 f8e 951d 647 de 9 B1 D8 e 11 ,
}
},
{
路径:"日志",
名称:"日志",
组件:日志,
元:{
标题: 日志管理,
角色: 14 bfbb 0337 ad 3 e 7 e 2c 9 fc 101294 C3 Fe 645 ,
}
},
{
路径:"角色",
名称:"角色",
组件:角色,
元:{
标题: 角色管理,
角色: 1559年D1 05d 15a 0 DCE 5549 b8 BF 5a 58c 0 cf 9 ,
}
}
]
}
]
导出默认设置
如果有一些详情页不需要在导航列表展示还可以添加字段,在生成导航栏时去掉
eg:
{
路径: addJoiner ,
姓名: addJoiner ,
组件:addJoiner,
元:{
hidden: true,//隐藏字段
标题: ***详情页,
角色: 14 bfbb 0337 ad 3 e 7 e 2c 9 fc 101294 C3 Fe 645 ,
}
},
3、登录获取权限集合和基本信息
//登录
登录(){
this.rememberPassword()
这个refs.form.validate((有效)={
如果(有效){
this.loading=true
让params={
登录名:this.form.user
密码:this.form.password,
代码:this.form.yanzhenma,
}
这个10.99美元API。发布( API/用户/登录,params).然后(res={
if (res.err_code===1) {
//把用户的基本信息储存在vuex,中
这个store.dispatch(setBaseInfo ,res.data).然后(()={
//获取有权限的路由表,添加到路由
router.addRoutes(this .$store.getters.addRouters)
这个. router.push({ name: home })
})
}
this.loading=false
})
}
})
部分vuex代码
如果不太理解,点击下面链接:
状态管理刷新就没了解决方案
秒懂状态管理
actions.js
//从" @/api "导入美国石油学会(American Petroleum Institute)
常量操作={
setBaseInfo ({
犯罪
},数据){
返回新承诺(resolve={
提交( set_userInfo ,data.userInfo)
提交(设置令牌,数据令牌)
提交(设置角色,数据.菜单)
//把基本信息保存在本地防止刷新之后丢失
会话存储。setitem( baseInfo ,JSON.stringify(data))
解决()
})
}
}
导出默认操作
突变。射流研究…
const setStorage=(key,value)={
if (typeof (value)===object) {
value=JSON.stringify(value)
}
sessionStorage.setItem(key,value)
}
/*
* 避免刷新之后状态管理被重置,在本地存储做一个备份
*/
常量突变={
set_userInfo(状态,有效负载){
state.userInfo=有效负载
setStorage(userInfo ,有效负载)
},
set_token(状态,有效负载){
state.token=有效负载
setStorage(token ,有效负载)
},
集合_角色(状态,有效负载){
状态。角色=有效负载
setStorage("角色",有效负载)
},
set_breadcrumb(状态,负载){
state.breadcrumb=有效负载
setStorage(breadcrumb ,有效负载)/* */
},
更改已折叠(状态,负载){
state.isCollapsed=有效负载
}
}
导出默认突变
getters.js
从" @/utils/createdRoutes.js "导入创建路由
从" @/router/index.js "导入{异步路由}
let getStoryage=(item)={
让str=会话存储。getitem(项目)
返回JSON.parse(str)
}
const getters={
get_userInfo: (state)={
返回state.userInfo?状态。userInfo:getStoryage( userInfo )
},
get_token: (state)={
返回state.token?状态。令牌:会话存储。getitem( token )
},
get_roles: (state)={
返回状态。角色。长度?state.roles : getStoryage("角色")
},
addRouters: (state,getters)={
let routes=createdRoutes(异步路由,getters.get_roles)
返回路线
},
get_breadcrumb: (state,getters)={
返回state.breadcrumb.length?状态。面包屑:getStoryage( getStoryage )
}
}
导出默认吸气剂
4、核心的筛选需要权限的路由方法:createdRoutes()
也就是3的吸气剂,用到的方法,毫无保留奉上
/**
* 判单当前的路由对象是否在登录人的权限之内
* @param {Array}角色权限
* @param {Object}路线路由
*/
函数具有权限(角色,路由){
如果(路线。元路由。meta。角色){//路由需要权限就要在权限数组里面判断
返回roles.includes(route.meta.role)
} else { //不需要权限就直接通过
返回真实的
}
}
/**
* 根据接口获取的权限列表动态生成当前用户的侧边导航栏,返回通过权限验证的路由数组
* @param {Array} asyncRoutes需要过滤的路由
* @param {Array}角色权限
*/
函数创建路由(异步路由,角色){
const accessedRouters=异步路由。过滤器(路由={
if (hasPermission(roles,route)) { //当前路由通过权限验证直接通过
如果(路线。儿童路线。孩子。长度){//当前路由有子路由,就递归验证
路线。孩子=创建的路线(路线。孩子、角色)
}
返回真实的
}
返回错误的
})
返回辅助路由器
}
导出默认创建的路由
5、处理刷新带来的问题
其实这里的代码是连接一的,注意注释
//全局的导航守卫
每个人之前到,从,下一个)={
//刷新页面之后导致某视频剪辑软件路由器和状态管理重置,路由丢失,利用的就是刷新后状态管理的状态被重置判断
if (to.name!==登录!store.state.token) {
//避免直接不登陆进页面
如果(!会话存储。getitem( token ){
location.href=/
返回
}
设data=JSON。解析(会话存储。getitem( baseInfo ))
store.dispatch(setBaseInfo ,data).然后(()={
VR。添加路线(商店。吸气剂。添加路由器)
})
}
//设置面包屑导航
让面包屑=到。匹配。过滤器(item=item。meta。标题)
if (breadcrumb.length) {
面包屑=面包屑。map(item=item。meta。标题)
store.commit(set_breadcrumb ,breadcrumb)
}
//设置标题
document.title=to。元标题
下一个()
})
6、侧边导航栏的完整代码
还是遍历的根据权限生成的路由表,干掉一些需要隐藏的详情页之类,
这里的代码和过滤l路由的核心函数,要根据自己的业务做相应的处理
元素-用户界面的菜单
模板
El-menu class= El-menu-vertical-demo :collapse= is collapsed background-color= # 545 c64 :default-active= active index text-color= # fff active-text-color= # 7 ea8f 5
添加路由器中的v-for=(项目,索引)部分:key= item。 name :class=是折叠的?已折叠":"
!-有子菜单-
El-子菜单:index= ` $ { index 1 } ` v-if=!项目。meta。隐藏项目。儿童项目。孩子。长度
模板槽=标题
I:class= ` icon icon font $ { item .meta。icon } ` /I
span slot= title"{ item。meta。title } }/span
/模板
项目.儿童中的v-for=(项目2,索引2)部分:key=item2.name
!-二级菜单有子菜单-
El-submenu:index= ` $ { index 1 }-$ { index 2 1 } ` v-if= item 2。儿童项目2。孩子。长度 class= sub 2
模板槽=标题
span slot= title"{ item 2。meta。title } }/span
/模板
!-三级菜单-
el-menu-item v-for=(item3,index3) in item2.children v-if=!项目3。meta。 hidden :index= item 3。 name :key= index 3 @ click。native= $ router。推({ name:item 3。name })
span slot= title"{ item 3。meta。title } }/span
/El-菜单项
/El-子菜单
!-二级菜单无子菜单-
!-不是隐藏的,详情页隐藏-
El-menu-item:index= item 2。name v-else-if=!项目2。meta。隐藏的 @ click。native= $ router。推({ name:item 2。name })
span slot= title"{ item 2。meta。title } }/span
/El-菜单项
/部分
/El-子菜单
!-无子菜单-
El-菜单项v-else-if= item。meta。隐藏项目。儿童项目。孩子。“length”:index=“item。儿童[0].名 @ click。native= $ router。推送({ name:item。儿童[0]).name}) class=item
I:class= ` icon font $ { item .儿童[0]。meta。icon } ` /I
span slot= title"{ item。儿童[0]。meta。title } }/span
/El-菜单项
/部分
/el-menu
/模板
脚本
从" vuex "导入{ mapGetters }
导出默认值{
道具:{
isCollapsed: {
类型:布尔型,
默认值:错误
}
},
计算值:{
.mapGetters([addRouters]),
activeIndex () { //集火的菜单
归还这个. route.name
}
}
}
/脚本
样式lang=scss 范围
部分{
/深/。埃尔-子菜单_ _标题{。图标{
右边距:10px
}
我{
颜色:白色;
字体大小:14px
}
}
/深/。埃尔-菜单项{
左填充:50px!重要;
}
/深/。埃尔-菜单-项目。项目{
左填充:19px!重要;
我{
颜色:白色;
字体大小:14px
右边距:12px
}
}
/深/。埃尔-子菜单100 . El-菜单项{
最小宽度:0;
}
/深/。el-submenu.sub2 .埃尔-子菜单_ _标题{
左填充:50px!重要;
我{
右边距:0px
}
}
/*/深/。el-submenu.sub2 .埃尔-菜单项{
文本缩进:12px
} */
}。折叠{
宽度:50px
/深/。埃尔-子菜单_ _标题{。埃尔图标-箭头-向右{
显示:无;
}
span[slot=title] {
显示:无;
}
}
}
/风格
路由图
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。