记一次 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


猜你喜欢

  • React 组件测试:使用 Enzyme 和 Mount 来测试

    React 组件是构建 Web 应用的重要组成部分,测试是开发过程中不可缺少的一环。在 React 中有很多测试方法,其中 Enzyme 和 Mount 是最常用的两种方法。

    15 天前
  • Mocha 测试中 chai 的异常断言技术

    在前端开发中,测试是不可或缺的环节。Mocha 是一款流行的 JavaScript 测试框架,它可以帮助开发者编写可靠的自动化测试用例。而 Chai 是 Mocha 的一个断言库,可以用来进行各种特定...

    15 天前
  • 解决 LESS 编译后 CSS 属性值为 0 时被删除的问题

    在前端开发中,我们经常使用 LESS 这样的 CSS 预处理器来提高开发效率,同时也可以让我们的样式更易于维护。然而,有时候我们会遇到一个问题:当我们在 LESS 中设置一个属性的值为 0 时,编译后...

    15 天前
  • Redis 在分布式场景中的部署与优化

    前言 Redis 是一个被广泛使用的高性能 key-value 内存数据库,极大的提升了程序的性能。在企业级应用程序的设计中,Redis 被广泛应用于各种功能场景,如会话缓存、排行榜、数据缓存等等。

    15 天前
  • Next.js 项目的 SEO 优化方案实例

    在现代 Web 开发中,搜索引擎优化 (SEO) 是一个至关重要的方面。特别是对于 Next.js 等 SSR 框架来说,优化 SEO 是尤为重要的,因为搜索引擎需要具备在服务器端渲染之后识别、爬取和...

    15 天前
  • 如何处理 RESTful API 中的加密和解密

    RESTful API 是很多前端开发人员在项目中必须要使用的一种技术。它可以方便地进行不同平台之间的数据传输,但是在传输过程中我们需要考虑到数据的安全性。因此,加密和解密是在 RESTful API...

    15 天前
  • SPA 开发中的 SEO 优化策略与实现方法

    前言 随着现代 Web 应用的发展,越来越多的开发者选择采用单页面应用(SPA)的架构来构建 Web 应用。使用 SPA 可以提供更加流畅的用户体验,提高应用的可维护性和扩展性。

    15 天前
  • 使用 GPU 加速提升网站性能

    在许多情况下,网站的性能瓶颈并不在后端或服务器端,而是在前端。特别是在处理大量数据或复杂动画时,前端渲染速度可能会变得非常缓慢。为了解决这个问题,可以使用 GPU 加速来提升网站性能。

    15 天前
  • 使用 Deno 和 Vue.js 构建单页面应用程序

    在开发单页面应用程序时,我们经常使用流行的前端框架,如 Vue.js。而 Deno,作为一种新型的 JavaScript 运行时,它提供了更好的安全性和可维护性,同时也能很好地与 Vue.js 配合使...

    15 天前
  • Kubernetes 上部署 MySQL 的实践经验

    如果您在使用 Kubernetes,您可能需要在 Kubernetes 集群上部署 MySQL 数据库。 在本文中,我们将介绍如何在 Kubernetes 上使用 Helm 部署 MySQL,以及如何...

    15 天前
  • 遇到 Firefox 浏览器 SSE 不兼容的问题?解决方案在这里!

    遇到 Firefox 浏览器 SSE 不兼容的问题?解决方案在这里! 在开发 Web 应用程序时,前端的服务器推送事件(Server-Sent Events)是一项非常实用的技术。

    16 天前
  • Redis 中的哈希表使用技巧

    前言 Redis 是一款高性能的内存键值存储系统。它支持多种数据结构,其中之一就是哈希表。哈希表是 Redis 中最为常用的数据结构之一,它可以在 O(1) 的时间复杂度下完成查找、插入、删除等操作,...

    16 天前
  • 如何使用 Next.js 实现 Fine-grained 静态资源映射

    本文将介绍如何使用 Next.js 中的 next.config.js 配置文件以及 getStaticProps 函数来实现 Fine-grained 静态资源映射。

    16 天前
  • 利用 ES2020 的 import 函数在 Webpack 中动态加载代码块

    Webpack 是一个流行的打包工具,它使得前端开发人员可以将代码打包成一个或多个文件。在 Webpack 中,我们可以使用 import 语法来导入模块或代码块。

    16 天前
  • Custom Elements:如何添加动态属性

    前言 Custom Elements 是 Web Components 的核心之一,它允许开发人员定义自己的 HTML 元素,这些元素可以拥有自己的行为、样式和属性。

    16 天前
  • 如何使用 Express.js 处理 POST 请求的文件上传

    当我们需要将客户端上传的文件保存到服务器,我们通常需要使用后端框架处理相关的请求。在 Node.js 中,Express.js 是最流行的 Web 应用程序框架之一。

    16 天前
  • Android 无障碍服务中 Activity 的 AccessibilityEvent 与 AccessibilityNodeInfo 的作用

    在 Android 中,无障碍服务可以帮助视力障碍者或者其他障碍者使用设备和应用程序。无障碍服务的一个关键概念就是 AccessibilityEvent 和 AccessibilityNodeInfo...

    16 天前
  • 如何结合 Tailwind CSS 和 Alpine.js 实现动态样式效果

    如何结合 Tailwind CSS 和 Alpine.js 实现动态样式效果 在前端开发中,我们经常需要实现一些动态样式效果,这些效果通常比较复杂,需要用到多个 CSS 属性,并且需要响应用户的交互事...

    16 天前
  • React Native+Mobx 跨平台状态管理

    React Native+Mobx 跨平台状态管理 在跨平台移动应用开发中,状态管理是至关重要的一环。传统的管理方式如 Props 和 Redux 往往会带来不必要的麻烦,导致代码复杂度的增加和维护难...

    16 天前
  • 如何优雅地使用 RxJs

    RxJs 是一个基于可观察数据流的编程库,它广泛应用于前端开发的状态管理、异步操作和响应式编程等方面。然而,由于 RxJs 的语言和概念比较抽象,初学者可能很难理解和应用它。

    16 天前

相关推荐

    暂无文章