VUE 路由守卫 next() / next({ ...to, replace: true }) / next(‘/‘) 说明
最近因为next()
遇到了不少问题,在这里记录一下
首先是路由守卫,是不是感觉简简单单
beforeEach((to, from, next) => {to // 要去的路由from // 当前路由next() // 放行的意思
}
但是在看别的项目时常常能看到next('/logon') 、 next(to) 或者 next({ ...to, replace: true })
这又是啥意思呢
其实在路由守卫中,只有next()
是放行,其他的诸如:next('/logon') 、 next(to) 或者 next({ ...to, replace: true })
都不是放行,而是:中断当前导航,执行新的导航
可以这么理解:
next()
是放行,但是如果next()
里有参数的话,next()
就像被重载一样,就有了不同的功能。
而对于上面说的中断当前导航,执行新的导航打个比方:
现在我有一个守卫,在守卫中我使用next('/logon')
,肯定有同学认为是会直接跳转到/logon
路由:
beforeEach((to, from, next) => {next('/logon')
}
然而年轻人不讲武德,执行时需要这么看:
beforeEach((to, from, next) => {beforeEach(('/logon', from, next) => {beforeEach(('/logon', from, next) => {beforeEach(('/logon', from, next) => {beforeEac... // 一直循环下去...... , 因为我们没有使用 next() 放行}}}
}
如果把这个守卫改一下,当我在地址栏输入/home
时
beforeEach((to, from, next) => {if(to.path === '/home') {next('/logon')} else {// 如果要去的地方不是 /home , 就放行next()}
}
我本来要去/home
路由,因此执行了第一次 beforeEach((to, from, next)
但是这个路由守卫中判断了如果要去的地方是'/home'
,就执行next('/logon')
,
所以想要访问/home
可以这么看
beforeEach((to, from, next) => {beforeEach(('/logon', from, next) => {next() // 现在要去的地方不是 /home , 因此放行}
}
注意:重点就在这,next('/logon')
不是说直接去/logon
路由,而是中断(不是CPU的那个中断!VUE中的中断就是此时不会执行router.afterEach(() => {}
)这一次路由守卫的操作,又进入一次路由守卫,就像嵌套一样,一层路由守卫,然后又是一层路由守卫,此时路由守卫进入到第二层时,to.path
已经不是/home
了,这个时候才执行next()
放行操作。
正以为如此很多人在使用动态添加路由addRoutes()
会遇到下面的情况:
在addRoutes()
之后第一次访问被添加的路由会白屏,这是因为刚刚addRoutes()
就立刻访问被添加的路由,然而此时addRoutes()
没有执行结束,因而找不到刚刚被添加的路由导致白屏。因此需要从新访问一次路由才行。
该如何解决这个问题 ?
此时就要使用next({ ...to, replace: true })
来确保addRoutes()
时动态添加的路由已经被完全加载上去。
next({ ...to, replace: true })
中的replace: true
只是一个设置信息,告诉VUE本次操作后,不能通过浏览器后退按钮,返回前一个路由。
因此next({ ...to, replace: true })
可以写成next({ ...to })
,不过你应该不希望用户在addRoutes()
还没有完成的时候,可以点击浏览器回退按钮搞事情吧。
其实next({ ...to })
的执行很简单,它会判断:
如果参数to
不能找到对应的路由的话,就再执行一次beforeEach((to, from, next)
直到其中的next({ ...to})
能找到对应的路由为止。
也就是说此时addRoutes()
已经完成啦,找到对应的路由之后,接下来将执行前往对应路由的beforeEach((to, from, next)
,因此需要用代码来判断这一次是否就是前往对应路由的beforeEach((to, from, next)
,如果是,就执行next()
放行。
如果守卫中没有正确的放行出口的话,会一直next({ ...to})
进入死循环 !!!
因此你还需要确保在当addRoutes()
已经完成时,所执行到的这一次beforeEach((to, from, next)
中有一个正确的next()
方向出口。
因此想实现动态添加路由的操作的话,代码应该是这样的:
router.beforeEach((to, from, next) => {const token = sessionStorage.getItem('access_token')// 存在 token 说明已经登录if (token) {// 登录过就不能访问登录界面,需要中断这一次路由守卫,执行下一次路由守卫,并且下一次守卫的to是主页'if (to.path === '/login') {next({ path: '/' })}// 保存在store中路由不为空则放行 (如果执行了刷新操作,则 store 里的路由为空,此时需要重新添加路由)if (store.getters.getRoutes.length || to.name != null) {//放行next()} else {// 将路由添加到 store 中,用来标记已添加动态路由store.commit('ADD_ROUTER', '需要添加的路由')router.addRoutes('需要添加的路由')// 如果 addRoutes 并未完成,路由守卫会一层一层的执行执行,直到 addRoutes 完成,找到对应的路由next({ ...to, replace: true })}} else {// 未登录时,注意 :在这里也许你的项目不只有 logon 不需要登录 ,register 等其他不需要登录的页面也需要处理if (to.path !== '/logon') {next({ path: '/logon' })} else {next()}}
万一还是听不懂,也可以next()
比作Java Filter
里的chain.doFilter(req, resp)
@WebFilter(filterName = "EncodingFilter", urlPatterns = "/*")
public class EncodingFilter implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {// 设置编码req.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");chain.doFilter(req, resp); // next()}}
VUE 路由守卫 next() / next({ ...to, replace: true }) / next(‘/‘) 说明相关推荐
- reactrouter4路由钩子_react router @4 和 vue路由 详解(八)vue路由守卫
13.vue路由守卫 a.beforeEach 全局守卫 (每个路由调用前都会触发,根据from和to来判断是哪个路由触发) const router = new VueRouter({ ... }) ...
- vue路由守卫死循环及next原理解释
在使用vue路由守卫的beforeEach方法时可能会出现无限递归,也就是死循环的问题,根本原因在于next()方法在不合适的地方错误调用所致,先来看一下官方对next()方法的解释: befor ...
- Vue路由守卫(导航守卫)及使用场景
目录 前言 一.路由守卫是什么? 二.路由守卫全解析 先来看一下钩子函数执行后输出的顺序吧 1.全局路由守卫 2.组件路由守卫 3.路由独享守卫 单独介绍一下路由守卫钩子三个参数 前言 最近在学习vu ...
- vue路由守卫中next方法的理解
vue路由守卫中next方法的理解 在网上看到了一篇通俗易懂的文章,此文章出处 在这里我用通俗点的说法解释上next(),next(false),next('/'),next(error),希望通过这 ...
- VUE路由守卫_前端实现权限验证
VUE路由守卫_权限验证 引言: 本文在利用SpringBoot和Vue实现前后端分离一文的基础上追加的路由守卫:未登录时会限制访问某些页面(前台控制),与之前的Shiro不同: 文章目录 VUE路由 ...
- vue路由守卫有哪三种类型
vue中路由守卫一共有三种,分别为:全局路由守卫(全局前置守卫.全局后置守卫),组件内路由守卫,路由独享守卫(是在路由配置页面单独给路由配置的一个守卫). 路由守卫,也可以是路由拦截,我们可以通过路由 ...
- vue路由守卫beforeEach和afterEach
路由守卫 路由前置守卫beforeEach 路由在每次切换之前,都会到用一个函数:beforeEach 举个简单的栗子:如果当前跳转的路由路径是/home或者/about时才能查看页面,否则提示无权限 ...
- Vue路由守卫(导航守卫)
路由守卫包括全局守卫(beforeEach()).路由独享守卫(beforeEnter()).组件内守卫(beforeRouteEnter().beforeRouteLeave()) 1.全局守卫(b ...
- vue路由守卫,axios拦截器,权限树
K15项目案例-后台 1.分页问题 关于分页表格列中的序号问题: <el-table-column type="selection" label="序号" ...
最新文章
- 解决办法:CMake编译时出现“error in configuration process project files may be invalid”
- 使用命令导入sql文件到mysql数据库时报Failed to open file错误的解决方案
- 微信小程序rpx作为高度单位时,在 ios 出现异常
- 使用Intent来启动Activity并传递参数
- 用nodejs xml2js读取xml文件
- 单片机实用工具大全,超级赞,工程师必备!
- Linux下rpm安装软件
- Excel2016 文件运行宏,出现可能是因为该宏在此工作簿中不可用,或者所有的宏都被禁用
- 基于单片机的指纹识别电子密码锁设计
- MFC 的List Control控件实现可编辑
- [转载] 杜拉拉升职记——14 猜猜为啥请晚餐
- android依赖本地工程排除,Android Gradle依赖项排除(Android Gradle dependency exclude)
- 京东个人注册开店要怎么做?京东开店步骤介绍!
- Acrel-1200分布式光伏运维平台
- EMC测试仪器_如何实现EMC的测试工作?
- 274. H 指数----中等
- lower_bound()函数和upper_bound函数
- 【pyqt】自制的图片裁剪分割器
- 卡尔曼滤波与组合导航原理_基于RAEKF的GPS/INS紧组合导航方法研究
- 高效的敏捷测试第十一课 敏捷测试分析、策略和方法