参考地址 https://forum.vuejs.org/t/vue-router-3-0-1-router-addroutes/33181/20
https://blog.csdn.net/qq_41912398/article/details/109231418 vue路由守卫next()/next({...to,replace:true})说明
https://blog.csdn.net/weixin_33935505/article/details/91414471 解决vue-router addRoutes 路由不刷新问题
关键语句: 在执行路由前置守卫前已经进行获取匹配了
进一步学习 (源码解析)
https://zhuanlan.zhihu.com/p/365641816
export const constantRoutes = [ { path: '/login', component: () => import('@/views/login'), hidden: true }, { path: '/404', component: () => import('@/views/404'), hidden: true }, // dashboard首页的规则 { path: '/', component: Layout, redirect: '/dashboard', // 重定向到/dashboard children: [ { path: 'dashboard', name: 'dashboard', component: () => import('@/views/dashboard'), meta: { title: '首页', icon: 'dashboard' } } ] }, // 上传组件的规则 { path: '/import', component: Layout, hidden: true, children: [ { path: '', name: 'import', component: () => import('@/components/Import') // meta: { title: '导入', icon: 'dashboard' } } ] } // 一定要放在最后上面的路由规则匹配不到对应的规则,会重定向到404页面 // { path: '*', redirect: '/404', hidden: true } // 动态路由规则 employees ]
提问:
1.为什么要注销 * 的路由地址
因为在刷新页面后,运行到执行前置守卫前已经开始进行获取匹配了,那么都不符合,那么就自然就找到了404,此时动态路由没还有加入进入.
// 导航前置守卫 router.beforeEach(async(to, from, next) => { NProgress.start() const token = store.getters.token // 判断token是否存在 if (token) { // 若token存在,去的是登录页,就进入首页 if (to.path === 'login') { next('/') NProgress.done() } else { console.log(!store.state.user.userInfo.userId) console.log('这是个球啊', to) // 若token存在,去的是别的页面,那么就放行,在跳转前就该获取用户信息 if (!store.state.user.userInfo.userId) { const { roles: { menus }} = await store.dispatch('user/getUserInfo') // 这里还需要做权限数据处理 router.addRoutes(asyncRoutes)
//输出来看看
console.log(router.options.routes) // 只有四个 //next() 不能写,而应该写成下面的 next({...to ,replace:true }) next({ ...to, replace: true // 处理刷新新的路由地址和旧的路由重复 }) return } next() } } else { // 若token不存在,但是在白名单上,放行 if (whiteList.includes(to.path)) { next() } else { // 若token不存在,也不再白名单上,不放行 next('/login') NProgress.done() } } })
提问:
1.next() 和 next({...to, replace:true}) 有什么区别?
next(): 只是放行
诸如 next('/'),next(to) 或者 next({...to,replace:true}) 都不是放行,而是 中断当前导航,执行新的导航
2.next({...to,replace:true}) 中replace的作用是什么 ?
next({...to,replace:true})一般是在动态路由问题上使用的,因为这样可以中断当前导航,执行新的导航. 如不这样写,每次进行刷新,就相当在浏览器留下一个记录,返回上一个页面时就会出现一直为当前页面
例如:c页面 到 a页面,没有设置replace:true,那么每次刷新五次后,返回上一个页面,那么依旧是在a页面,知道五次之后,才会回到c页面.
3.那么在路由中只写next(to),而不写next() 可以吗?
案例, 在守卫中使用next('/login'),肯定有同学认为会直接跳转到/login路由
beforeEach((to, from, next) => { next('/logon') }
实际上:
beforeEach((to, from, next) => { beforeEach(('/logon', from, next) => { beforeEach(('/logon', from, next) => { beforeEach(('/logon', from, next) => { beforeEac... // 一直循环下去...... , 因为我们没有使用 next() 放行 } })
})
})
4. 为什么 router.options.routes 在执行 router.addRoutes(asyncRoutes) 之后,没有进行更新?(看上面代码)
答:可能是存在bug
扩展:
vue中页面刷新后,对于路由来说所走的流程:
vue加载main.js =>main.js调用router =>获取浏览器URL =>router根据路由表找对应的组件=>找到对应的组件,加载组件(在加载组件前router.beforEach()) =>显示页面
在做权限功能的时候,需要思考哪些问题
1.在登录成功后,通过前置守卫去处理权限信息
2.判断是否有登录的权限信息,若没有就获取
3.获取登录人的权限信息后,将此信息与项目配置的路由信息进行比较筛选,静态路由的权限和动态路由相结合,通过vuex保存在缓存中
4.在退出时,通过router实例的 matcher 将路由进行重置 (可写可不写)