最近公司前台一直在使用vue,其中一个项目决定使用iview UI库,为了方便我们就使用了官方提供的iview-admin后台模板。可我这个菜鸡使用起来举步维艰,下面给大家介绍一下我们实现动态菜单的可行方案。
思路
- 将所有的路由在项目的
router/routers.js
文件中定义好,一定要按照人家的格式定义。如果是左侧菜单,必须type:"menu"
。并且全部的路由定义时都hideInMenu: true
默认隐藏。【默认隐藏为了给动态显示菜单做铺垫,当用户有某某个路由时,我们才显示某个路由,即hideInMenu: false
】 - 登录成功后将用户的认证信息保存到客户端,如vux、localstorage,但vuex刷新页面会丢失。
- 进入首页时,通过路由加载菜单
yes,就是这个思路,下面我们具体讲解每一步的实现。
定义routers
额…没有那么高大上,就是在人家iview-admin现成的文件中写入我们自己的路由。编写路由的规范,可以跳到我另一篇:iview-admin路由介绍
代码实现
iview admin的main.vue组件中的导航菜单组件引用的值menuList便是我们要注意的重点。
vuex中的menuList
我们着重关注app.js中的getMenuByRouter()
str :用户拥有哪些路由的数组json串,存的是router的name
let str = ''
let arr = ''
export const getMenuByRouter = (list, access) => {
str = localStorage.getItem('auth_info') // 登录成功后,后台传入的该用户拥有的路由数组
arr = JSON.parse(str)
if (arr == null) return false;
let res = []
forEach(list, item => {
if (arr.indexOf(item.name) >= 0 && item.meta.type == 'menu') {
item.meta.hideInMenu = false
}
if (!item.meta || (item.meta && !item.meta.hideInMenu)) {
let obj = {
icon: (item.meta && item.meta.icon) || '',
name: item.name,
meta: item.meta
}
if ((hasChild(item) || (item.meta && item.meta.showAlways))
&& showThisMenuEle(item, access)) {
obj.children = getMenuByRouter(item.children, access)
}
if (item.meta && item.meta.href) obj.href = item.meta.href
if (showThisMenuEle(item, access)) res.push(obj)
}
})
return res
}
为什么根据用户拥有路由,通过遍历就可以动态菜单?
所有的路由我们已经在前台的routers定义好了,默认都是隐藏的。在这遍历用户拥有的路由,判断我们的routers.js中全部路由是否包含用户拥有的路由,将用户拥有的路由,并且是type:menu
的,hideInMenu: false
设置为false,即显示出来!
本文侧重于提供思路,如果需要源码的话就评论留下联系方式 ~