一、了解动态路由
我这里说的动态路由指的是,由后端提供当前角色可以访问的所有路径,前端提前写好路径与组件之间的映射也就是route,然后根据后端返回的url进行匹配,将匹配到的route加入到router里面。
后端返回的数据大概是这样:
提前写好的route的path一定要和上面的url对应:
export default {
path: '/main/analysis/overview',
name: 'overview',
component: overview,
children: []
}
动态添加就是遍历咱们上面提前写好的所有routes,看有没有和后端返回的url一样的,有到时候我们就先放到数组routes里,后面通过router.addRoute加入到路由里面去即可:
const routes = mapMenusToRoutes(userMenu)
routes.forEach((route) => {
router.addRoute('main', route)
})
好了,知道了什么是动态路由后,来看看我遇到的问题吧,就是刷新页面后,不能正常跳转,匹配的组件有问题,但是最奇怪的是打印出来的路由映射又没有问题?
二、解决问题
我用了全局导航守卫beforeEach,也是没有用,刷新会出问题,然后我就打印了router.getRoutes()以及beforeEach中回调的to参数:
看,router.getRoutes()得到的routes是没问题的,那为什么不能跳转!!!
答案其实是js执行顺序问题,to里面的name属性明显有问题,not-find对应的是404组件,为什么呢?
我们来看下面就知道答案了:
app.use(router)
app.use(store)
// 初始化store
setupStore()
app.mount('#app')
setupStore函数里面就有动态添加路由,众所周知:app.use()的本质是,执行里面的回调函数(如果是对象就执行里面的install方法),而router对象的install在执行后会立马获取当前的路径,然后和现有的routers进行匹配,并确定好要前往的组件,上面to对象的name就是证据。所以即使我们使用了导航守卫也是不行的!因为人家都匹配好了,你才将映射加入routes,有什么用呢
so,解决的办法也很简单将动添加路由的逻辑setupStore()放app.use(router)上面即可
结论
这次问题的出现也告诉了我,代码的执行顺序很重要,其次是导航守卫的本质就是一个互调函数,不能光从字面来解读和使用,就行这次它在install之后执行一样。