1.在登陆成功后,后台会返回用户菜单权限,例如:
//一种菜单返回格式,也可以是无限极数据或者其他格式
[
//有二级菜单的
{
label: "人员管理",
children: [
{
label: "监察员管理",//对应菜单名
path: "/inspector",//对应路由
name: "inspector",//对应路由名
url: "inspector/Inspector"//对用vue文件路径
icon:"*****"//若有图标,则对应icon图标
},
{
label: "人员处分档案",
path: "/punish",
name: "punish",
url: "inspector/Punish"
}
]
},
//无二级菜单的
{
label: "廉政教育",
path: "/government",
name: "government",
url: "government/Government"
},
//跳转单独路由但是菜单不显示的
{
label: "查看",
path: "/inspector.display",
name: "inspector.display",
url: "inspector/Inspector.display",
hidden: true//在菜单遍历时判断hidden为false显示
},
{
label: "查看",
path: "/punish.display",
name: "punish.display",
url: "inspector/Punish.display",
hidden: true
},
{
label: "反馈",
path: "/feedback.feedback",
name: "feedback.feedback",
url: "supervise/Feedback.feedback",
hidden: true
},
{
label: "查看",
path: "/supervise.display",
name: "supervise.display",
url: "supervise/Supervise.display",
hidden: true
},
{
label: "查看",
path: "/government.display",
name: "government.display",
url: "government/Government.display",
hidden: true
},
]
2.将拿到的menu数据存到store中
this.$store.commit("menuList", menu数据)
3.在store的mutations对应方法中
// 菜单列表
menuList(state, val) {
state.menu = val //修改state中menu状态
localStorage.setItem("menu", JSON.stringify(val)) //将menu存储到本地,避免页面刷新数据丢失,也可以在全局前置路由守卫中判断state中menu的长度是否为0,如果为0重新请求数据
},
4.在封装的menu组件中
menu() {
//如果state中menu长度为0则读取本地数据否则读取state中的数据
return this.$store.state.menu.length ? this.$store.state.menu : JSON.parse(localStorage.getItem("menu"))
}
5.添加动态路由
//在登陆成功后调用store中的mutations方法,传入路由
this.$store.commit("router", this.$router)
6.在store的mutations对应方法中
// 动态路由
router(state, router) {
//判断token是否存在
if (!localStorage.getItem("token")) return
let menu = JSON.parse(localStorage.getItem("menu"))
state.menu = menu
let menuArr = []
menu.forEach(item => {
//因为item中以包含path,name等,所以只需要添加component属性,然后将item添加到数组中
//判断是否存在子菜单,如果存在子菜单,则需要配置路由的数据为children中的数据,父级菜单并不存在路由
if (item.children) {
//如果有子路由,则需要添加children属性
item.children.forEach(citem => {
citem.component = () => import(`../views/${citem.url}`)
})
menuArr.push(...item.children)
} else {
//无子菜单
item.component = () => import(`../views/${item.url}`)
menuArr.push(item)
}
})
//遍历存放路由的数组
menuArr.forEach(v => {
router.addRoute('home', v)//将每一项添加到路由home下,即作为路由home的子路由
})
},
7.完成以上操作后,存在刷新页面白屏问题,需要在main.js中进行配置
created() {
store.commit("router", router)
},
8.在main.js中配置全局前置守卫
router.beforeEach((to, from, next) => {
let token = localStorage.getItem("token")
if (!token && to.name !== 'login') {
next({ name: "login" })
} else {
next()
}
})
注:全局前置守卫以及动态添加路由的操作也可以配置在router下的js文件中,只是看了视频觉的这种方法更适合目前的我理解~~~