当前位置: 首页 > news >正文

复制标签页导致的Vue动态路由失效问题解决思路

先透一下题,本次问题是因为未正确理解Vue和浏览器的整体生命周期导致的问题。

背景

自己开发的快速开发框架,前端自己开发的动态路由,但我发现通过浏览器复制标签页打开的新标签页无法加载动态路由。

复制标签页

打开的界面完全空白,因为找不到相关路由。

无法正常加载路由

开发环境

这里主要说明一下相关的主要环境:

Vue 2.7、Vue Router 3.6

排查问题

现在的动态路由逻辑

下面是动态路由的逻辑是:

1、监听浏览器的刷新事件,该事件会记录需要刷新动态路由的标识位。代码如下所示:

window.onbeforeunload = function () { // 刷新会触发这个事件if(window.localStorage.getItem("resources")){sessionStorage.setItem("RefreshRouter", false);}
};

同时在App.vue文件中的created生命周期方法中也进行设置该值:

export default {name: 'App',created(){if(window.localStorage.getItem("resources")){sessionStorage.setItem("RefreshRouter", false);}}
}

2、设置Vue Router的全局前置守卫配置,每次跳转路由时检查RefreshRouter标识位。

import router from '@/core/router.js'
// 设置全局前置守卫配置
router.beforeEach((to, from, next) => {RouterUtils.refreshRouter(router,to).then(() => {/* 其他逻辑 */next()})
});

这里的关键方法是RouterUtils中的refreshRouter方法,下面是这个方法的完整代码:

refreshRouter: function (router,to) {return new Promise((resolve, reject) => {try {if (window.localStorage.getItem("resources") && !JSON.parse(sessionStorage.getItem("RefreshRouter"))) {sessionStorage.setItem("RefreshRouter", true);this.addRoutes(JSON.parse(window.localStorage.getItem("resources"))).then(() => {router.push(to);resolve(); // 所有路由添加完成后调用 resolve()});} else {resolve();}} catch (error) {reject(error);}});
},

这个方法中主要检查了当前缓存中是否存在动态路由数据,如果存在再检查当前刷新动态路由的标识位,如果都符合要求,则执行动态添加路由操作并跳转到目标路由地址。

寻找问题

在目前的动态路由逻辑中,即使在浏览器地址栏复制路由地址 -> 粘贴路由地址直接访问也是可以正常加载动态路由并跳转的,如下图所示:

复制路由地址

为了直观的看到加载顺序,分别在window.onbeforeunload中、refreshRouter方法中各添加数字顺序打印。

代码示例如下所示:

window.onbeforeunload = function () { // 刷新会触发这个事件console.log(1)if(window.localStorage.getItem("resources")){sessionStorage.setItem("RefreshRouter", false);}
};export default {name: 'App',created(){if(window.localStorage.getItem("resources")){console.log(1)sessionStorage.setItem("RefreshRouter", false);}}
}refreshRouter: function (router,to) {return new Promise((resolve, reject) => {try {if (window.localStorage.getItem("resources") && !JSON.parse(sessionStorage.getItem("RefreshRouter"))) {console.log(2)sessionStorage.setItem("RefreshRouter", true);this.addRoutes(JSON.parse(window.localStorage.getItem("resources"))).then(() => {router.push(to);resolve(); // 所有路由添加完成后调用 resolve()});} else {console.log(3)resolve();}} catch (error) {reject(error);}});
},

先来一个正常的执行过程,在地址栏直接粘贴路由地址查看控制台打印顺序,正常加载动态路由:

粘贴路由地址查看控制台打印日志

通过复制标签页打开一个新窗口,查看控制台日志打印顺序:

复制标签页查看控制台打印日志

理想中的状态应该是先设置刷新路由标识未,再进行加载动态路由,但通过复制标签页打开新窗口顺序是相反的,有了解其中原因的朋友可以说一下,我这里就不继续往下深究了。

解决问题

将原来监听刷新事件的方法和App.vue中created生命周期方法中设置刷新动态路由标识的代码全部删除。

在main.js中初始化Vue Router之前增加动态路由标识,此步骤能保证不管什么生命周期都会被触发:

import router from '@/core/router.js'
if(window.localStorage.getItem("resources")){console.log(1)sessionStorage.setItem("RefreshRouter", false);
}
// 设置全局前置守卫配置
router.beforeEach((to, from, next) => {RouterUtils.refreshRouter(router,to).then(() => {// 其他逻辑next()})
});

验证一下结果是否正确,通过刷新界面、复制粘贴地址栏地址、复制标签页结果都可以正常展示界面内容,动态路由都可以被正常加载,控制台查看一下日志打印是否正常:

修正后查看日志打印

OK,大功告成!

总结

本文主要是因为没有理解透彻浏览器中Vue项目的生命周期,导致自己设计的动态路由组件在复制标签页打开新页面时无法正常加载动态路由,导致页面白屏。

经过一系列调试后,在main.js中初始化Vue Router前就设置标识位,保证在各种情况下都可以正常加载动态路由。

http://www.dtcms.com/a/435313.html

相关文章:

  • 从零起步学习Redis || 第六章:Redis单线程模式的实现详解
  • 影视公司网站设计河南省建设厅厅长
  • PySide6 新(建)窗口 简单示例
  • 逍遥WEBP图片转换组件XiaoyaoWebp.dll
  • 网站建设公司+长春建设部质监局网站
  • Oracle的connect by level在MySQL中的华丽变身
  • wordpress 便签四川旅游seo整站优化站优化
  • K8s基础原理
  • 学习Java第二十八天——黑马点评26~32
  • QML学习笔记(二十三)QML的MouseArea的drag
  • 数据驱动下的GBDT实战指南:从原理拆解到业务落地的方法论
  • 欧拉-马歇罗尼常数
  • 一款基于STM32F103和树莓派的无人车
  • ORB_SLAM2原理及代码解析:MapPoint::UpdateNormalAndDepth() 函数
  • 4-2. 二叉搜索树 (BST)
  • 做英文网站的标准字体鱼巴士设计师服务平台
  • 做网站流量是什么珠海网站建设优化
  • NTLite(操作系统定制工具)
  • 模块即服务?厘清 Linux 系统服务与微服务架构的本质区别
  • 成都电商网站开发免费送的广告怎么在网站上做
  • 熊猫网站ppt外贸网建站
  • 设计模式第六章(观察者模式)
  • C4D R20新增功能平滑滤镜和调整外形滤镜深度解析
  • 数据安全风险评估
  • 动漫共和国 | window版本
  • 校园网站如何建立在浙学网页设计与制作答案
  • 企业创建网站的途径都有啥深圳市浩天建设网站
  • 做外贸国外网站苏宁电器网站建设特点分析
  • AI自动化测试:接口测试全流程自动化的实现方法——技术深度与行业实践剖析
  • LeeCode 328. 奇偶链表