【vue】vue动态展示左侧菜单
VUE动态展示左侧菜单
·
VUE动态展示左侧菜单
在我们实际项目开发中经常会有这样的需求,不同的用户登录系统展示不同的菜单权限,
1.效果图
管理员登录系统
普通用户登录系统
普通用户的权限比管理员的权限小,所有没有展示系统管理、系统日志
二个菜单
2.实现代码
1.后台返回的数据结构
2.前面项目模板
https://panjiachen.github.io/vue-element-admin-site/zh/guide/
1.这里按需求下载模板
2.下载好项目解压完成用编辑器打开项目
3.首先封装后台返回的数据到vuex
状态管理中
1.在 src\store\modules 目录下新建一个文件menu.js
后台请求接口,和cookie自行百度封装这里就不贴代码,
menu.js
完整代码
import {getUserAuthority} from '@/api/user'
import {PcCookie,Key} from '@/utils/cookie'
// 定义状态
const state = {
// 初始加载状态
init: false,
// 菜单数据
menuList: [],
// 按钮数据
buttonList: []
}
// 改变状态
const mutations = {
SET_SYSTEM_MENU: (state,data) =>{
state.init = true
state.menuList = data.userMenuList
state.buttonList = data.userButtonList
}
}
// 定义行为
const actions = {
GetUserMenu({commit}){
return new Promise((resolve,reject) =>{
// 获取用户Id
const userId = PcCookie.get(Key.userInfoKey) ? JSON.parse(PcCookie.get(Key.userInfoKey)).id : null
// 发送请求
if(userId){
getUserAuthority({userId:userId}).then(res =>{
// 获取到数据,将菜单和按钮保存到vuex状态管理中
commit('SET_SYSTEM_MENU',res.data)
// 正常钩子
resolve()
}).catch(error=>{
// 异常钩子
reject(error)
})
}
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
2.写完menu.js
代码把定义的状态添加到getters.js
文件中
3.然后再permission.js
触发定义的状态
4.动态展示左侧菜单
1.找到左侧菜单栏的代码(src\layout\components\Sidebar\index.vue)
默认左侧菜单是从路由表获取的,现在我们不用默认的路由表数据,而是从后台返回的数据中获取路由信息,这边需要自己获取后台返回的数据保存到
vuex
状态管理中,然后修改对应代码,
第一从vuex状态管理中获取菜单数据,
第二传递给子组件,
第三把默认的从路由表获取数据的代码注释
具体的属性名看后台返回的名字
2 这边他引用了一个子组件 SidebarItem
我们找到子组件修改就可以了
3.子组件完整代码
<template>
<div>
<!-- 没有子菜单只有一级菜单 -->
<template v-if="!item.children || item.children.length === 0">
<app-link :to="item.path">
<el-menu-item :index="item.path" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="item.icon" :title="item.menuName" />
</el-menu-item>
</app-link>
</template>
<el-submenu v-else ref="subMenu" :index="item.menuId" popper-append-to-body>
<template slot="title">
<item :icon="item.icon" :title="item.menuName" />
</template>
<sidebar-item
v-for="child in item.children"
:key="child.menuId"
:is-nest="true"
:item="child"
class="nest-menu"
/>
</el-submenu>
</div>
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'
export default {
name: 'SidebarItem',
components: { Item, AppLink },
mixins: [FixiOSBug],
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
}
},
data() {
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this.onlyOneChild = null
return {}
},
methods: {
hasOneShowingChild(children = [], parent) {
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
}
return false
},
resolvePath(routePath) {
if (isExternal(routePath)) {
return routePath
}
if (isExternal(this.basePath)) {
return this.basePath
}
return path.resolve(this.basePath, routePath)
}
}
}
</script>
4.注意后台返回的数据中的路由地址要跟路由表的数据一致,不然点击菜单会跳转到404页面
路由表的数据如下
更多推荐
已为社区贡献8条内容
所有评论(0)