第一步,获取用户权限信息,将用户权限数据存入store
实现逻辑:在store的user模块中写下获取用户权限的方法
const state = {
userInfo: {},
menus:[],
point:[]
}
const mutations = {
// 存储用户信息方法
initUserInfo(state, data) {
state.userInfo = data
},
// 登出,删除本地token与store的用户信息
logout(state) {
delToken()
state = {}
},
// 存储用户权限信息方法
getPermFn(state,data2){
state.menus = data2.data.menus
state.point = data2.data.points
}
}
const actions = {
// 异步调用接口并调用方法存储用户信息
async getUserInfo(store) {
const data = await getUserInfo()
const data2 = await getPerm()
store.commit('initUserInfo', data.data)
store.commit('getPermFn',data2)
}
}
第二步:每次跳转页面都判断一下store里面有无用户信息,若没有,则调用储存用户信息方法
实现逻辑:在导航守卫中实现,在有token的状态下,每次跳转都要进行一次判断
// 每次进入一个页面都检查一边有没有数据
if (Object.keys(store.state.user.userInfo).length === 0) {
// 检查到用户信息没有时的时候调用获取用户信息方法
await store.dispatch('user/getUserInfo')
第三步,封装暴露所有的动态路由对象,并新建store的permission模块,引入动态路由对象与静态路由对现象
实现逻辑:把动态路由对象单独拿出来封装暴露,就是先切断了所有的动态路由
export const asyncRouters = {
...动态路由对象
}
export const constantRouters = {
...基础的路由对象(默认存在的页面)
}
store的permission模块中:
import { asyncRouter, constantRouters} from '@/router'
**第四步,在permission模块中写入根据用户权限过滤动态路由与合并并存储完整的路由对象数组方法
实现逻辑:在permission模块中写个方法,能够根据用户权限处理完整路由对象数组的
const state = {
// 存储过滤后的路由对象
router:[]
}
const mutations = {
// 拼接路由对象方法
setRouter(state,router){
state.router = [
...constantRoutes,
...router
]
}
}
const actions = {
// 过滤动态路由方法
filterRouter(store,menus){
// 声明一个变量接收过滤后的数组
const router = asyncRouter.filter(item=>{
return menus.indexOf(item.name) !== -1
})
// 调用方法设置总路由数组
store.commit('setRouter',router)
// 返回值为动态路由数组
return router
}
}
第五步,在导航守卫中调用permission中的过滤路由对象数组的方法,并接收返回值
实现逻辑:在调用获取并存储用户权限信息的方法后,再声明一个变量接收用户的权限,作为参数调用store的permission模块的过滤路由对象数组方法,通过async await 接收返回值
if (Object.keys(store.state.user.userInfo).length === 0) {
// 检查到用户信息没有时的时候调用获取用户信息方法
await store.dispatch('user/getUserInfo')
// 接收刚刚存储到store里面的用户权限数据
const menus = store.state.user.menus
// 作为参数调用处理动态路由对象的方法,并通过async await接收这个方法返回的过滤后的动态路由数组
const routers = await store.dispatch('permission/filterRouter',menus)
// 在这里添加动态路由对象,配置路由规则
router.addRoutes([
...routers,
// 这里404页面要放最后,不然如果*在其他路由前面的话,先找到*的话就会跳到404页面
{ path: '*', redirect: '/404', hidden: true }
])
第六步,处理在动态路由跳转的页面刷新,会跳转到空白页的bug
实现逻辑:因为刷新会先清空store里面存储的用户信息,再进行跳转,再进入这个页面时重新获取用户信息并存储,所有在跳转的时候,store里面的用户信息为空,动态路由对象(包括*的404页面)也还没有被配置到router里面,所以跳转的页面为空白。
解决方法,在获取完用户信息,配置完动态路由对象之后再利用next跳转一次,这次需要告诉next跳转的路径,这样就能在有用户信息的情况下跳转了 总结:一次刷新两次跳转,第一次有路径但没数据,获取完信息配置完路由之后会再跳转一次,这次有信息但没有路径,所以需要告诉next跳转的路径 next(to.path)
第七步,配置侧边栏显示栏目‘
实现逻辑:在layout的sideBar组件中获取存储到store.permission的完整路由对象数组
routes() {
return this.$store.state.permission.router
},