记一次 vue-router 的重定向问题解决过程

背景

我们团队一个前端小组使用 Vue.js 进行开发,项目中使用了 vue-router 进行路由管理。在某次项目迭代中,我们新增了一个权限管理模块,并需要在特定情况下跳转到登录页。经过开发,我们使用了 vue-router 的 meta 字段进行权限控制,并使用 router.beforeEach 钩子函数进行拦截。

---------------------- ----- ----- -- -
  ----- ------------ - ---------------------- -- --------------------------
  ----- ---------- - ----------------------

  -- ------------- -- ------------ -
    ---------------
  - ---- -
    -------
  -
---

这段代码的意思是:当路由需要进行权限控制,并且用户没有登录时,拦截跳转到登录页面。这段代码运行良好,我们测试通过后提交了上线。但是,在线上环境中出现了重定向问题。

问题

我们发现,在某些情况下,当跳转到登录页面后再返回原先的页面时,页面总是被重定向到登录页。使用开发者工具进行调试,发现跳转流程如下:

  1. 用户进入需要登录的页面,被 beforeEach 拦截,跳转到登录页;
  2. 用户填写登录信息并登录后,跳转回原来的页面;
  3. 在一些特定情况下,页面会重定向到登录页。

这个问题出现的场景非常具有偶然性,我们一开始并没有很好地排查到问题所在。

排查

针对这个问题,我们进行了如下的排查:

  1. 调整了跳转逻辑,尝试使用 next({ path: '/login' }); 的方式进行跳转,但问题依旧,说明是代码逻辑上的问题;
  2. 在路由拦截器中加入大量 console 输出,查看跳转前后的路由信息、 meta、 用户登录状态等,发现无法得到任何有效信息;
  3. 调整了 Vue.js、 Vue-router 的版本,但问题没有解决。

我们认为这个问题和路由的缓存有关系,但一直无法彻底解决。直到有天,我们查看路由缓存机制文档时,发现了这么一段话:

"注意,默认情况下,Vue.js 是开启路由缓存的,因此,当你使用了 router.go(-1) 或浏览器的返回按钮返回到路由时,Vue-router 会从缓存中取得路由信息并直接显示,没有经过 beforeEach、beforeResolve 钩子函数的拦截。"

我们认为这句话就是问题的关键所在,我们使用的是 router.go(-1) 进行返回按钮操作,但是这样就跳过了拦截器的执行。因此,当页面重定向回来时,拦截函数没有被执行,导致了跳转问题。

解决

我们的解决方案非常简单,禁用路由缓存,强制让每一次返回操作都重新加载:

----- ------ - --- -----------
  ----- ----------
  -------
  ------------------ ----- -------------- -
    ------ - -- -- -- - --
  --
  -- -----------
  -------------------- ----- ----- -
    ------------------- - ------
    -------
  --
  -------------------- ----- ----- -
    -- ------------------ --- ----- -
      ------------------- - ------
    -
    -------
  -
---

在之前,我们还没有学习到这个解决方案,但这一次排查之后,我们意识到开发过程中代码的运行环境和测试环境可能存在差异,需要在排查问题时仔细地分析环境和代码逻辑,不能仅仅靠根据开发过程中的语法和调试工具进行排查。同时,我们对 Vue.js 和 Vue-router 的缓存机制有了更深入的了解,这对我们后续的开发也非常有帮助。

结论

通过这次问题的排查和解决,我们学到了以下内容:

  1. Vue.js 和 Vue-router 的缓存机制;
  2. Vue-router 的跳转流程;
  3. 跳转逻辑的影响可以有很多,环境差异和用户操作丰富程度都需要考虑;
  4. 排查问题需要深入代码,在开发过程中需要多加留意细节问题。

参考

Vue-router 官方文档:https://router.vuejs.org/zh/guide/advanced/keep-alive.html#%E5%9C%A8%E7%8B%AC%E7%AB%8B%E7%BB%84%E4%BB%B6%E4%B8%AD%E5%8F%96%E6%B6%88%E7%BC%93%E5%AD%98

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/66fc66a444713626016d90e9