最近因为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(‘/‘) 说明相关推荐

  1. reactrouter4路由钩子_react router @4 和 vue路由 详解(八)vue路由守卫

    13.vue路由守卫 a.beforeEach 全局守卫 (每个路由调用前都会触发,根据from和to来判断是哪个路由触发) const router = new VueRouter({ ... }) ...

  2. vue路由守卫死循环及next原理解释

    ​ 在使用vue路由守卫的beforeEach方法时可能会出现无限递归,也就是死循环的问题,根本原因在于next()方法在不合适的地方错误调用所致,先来看一下官方对next()方法的解释: befor ...

  3. Vue路由守卫(导航守卫)及使用场景

    目录 前言 一.路由守卫是什么? 二.路由守卫全解析 先来看一下钩子函数执行后输出的顺序吧 1.全局路由守卫 2.组件路由守卫 3.路由独享守卫 单独介绍一下路由守卫钩子三个参数 前言 最近在学习vu ...

  4. vue路由守卫中next方法的理解

    vue路由守卫中next方法的理解 在网上看到了一篇通俗易懂的文章,此文章出处 在这里我用通俗点的说法解释上next(),next(false),next('/'),next(error),希望通过这 ...

  5. VUE路由守卫_前端实现权限验证

    VUE路由守卫_权限验证 引言: 本文在利用SpringBoot和Vue实现前后端分离一文的基础上追加的路由守卫:未登录时会限制访问某些页面(前台控制),与之前的Shiro不同: 文章目录 VUE路由 ...

  6. vue路由守卫有哪三种类型

    vue中路由守卫一共有三种,分别为:全局路由守卫(全局前置守卫.全局后置守卫),组件内路由守卫,路由独享守卫(是在路由配置页面单独给路由配置的一个守卫). 路由守卫,也可以是路由拦截,我们可以通过路由 ...

  7. vue路由守卫beforeEach和afterEach

    路由守卫 路由前置守卫beforeEach 路由在每次切换之前,都会到用一个函数:beforeEach 举个简单的栗子:如果当前跳转的路由路径是/home或者/about时才能查看页面,否则提示无权限 ...

  8. Vue路由守卫(导航守卫)

    路由守卫包括全局守卫(beforeEach()).路由独享守卫(beforeEnter()).组件内守卫(beforeRouteEnter().beforeRouteLeave()) 1.全局守卫(b ...

  9. vue路由守卫,axios拦截器,权限树

    K15项目案例-后台 1.分页问题 关于分页表格列中的序号问题: <el-table-column type="selection" label="序号" ...

最新文章

  1. 解决办法:CMake编译时出现“error in configuration process project files may be invalid”
  2. 使用命令导入sql文件到mysql数据库时报Failed to open file错误的解决方案
  3. 微信小程序rpx作为高度单位时,在 ios 出现异常
  4. 使用Intent来启动Activity并传递参数
  5. 用nodejs xml2js读取xml文件
  6. 单片机实用工具大全,超级赞,工程师必备!
  7. Linux下rpm安装软件
  8. Excel2016 文件运行宏,出现可能是因为该宏在此工作簿中不可用,或者所有的宏都被禁用
  9. 基于单片机的指纹识别电子密码锁设计
  10. MFC 的List Control控件实现可编辑
  11. [转载] 杜拉拉升职记——14 猜猜为啥请晚餐
  12. android依赖本地工程排除,Android Gradle依赖项排除(Android Gradle dependency exclude)
  13. 京东个人注册开店要怎么做?京东开店步骤介绍!
  14. Acrel-1200分布式光伏运维平台
  15. EMC测试仪器_如何实现EMC的测试工作?
  16. 274. H 指数----中等
  17. lower_bound()函数和upper_bound函数
  18. 【pyqt】自制的图片裁剪分割器
  19. 卡尔曼滤波与组合导航原理_基于RAEKF的GPS/INS紧组合导航方法研究
  20. 高效的敏捷测试第十一课 敏捷测试分析、策略和方法

热门文章

  1. 二值图像的形态学处理
  2. mac 查ip linux,如何通过mac地址查ip,手把手教你Mac怎么查看ip地址
  3. 2021.5.22 2022蓝桥杯练习赛3
  4. java代码人为模拟股票的变动
  5. Windows上最好用的5款epub阅读器
  6. 论OpenVZ与KVM的区别
  7. php判断图片有没有ps过,鉴别P图,如何鉴别图片是否被P过
  8. android rom 寿命,手机寿命有多长?苹果用3年而安卓只有2年
  9. Stitch Fix玩转时尚算法,年销7.3亿
  10. 微信公众平台为什么会火