popstate监听浏览器的前进后退事件

最近遇到一个需求,讲的是有一个页面,从头到尾都是一个路由,是通过el-tabs的activeName来切换当前页面的。

但是呢,需求方认为,每次刷新页面,都会回到第一个页面,并且后退的话,也不是我的上一个tab页,而是上一个新的单页面,不符合直观上的感受,改!

分析一下需求:核心其实就是记录已经操作过的页面的标识,以便我在刷新重新加载,或者路由回退的时候找到它。

由于是一个大的tab页,更换路由显然不太行。那么就有两种方案。

一种是自己维护一个数组,每次操作都往里面添加一个数据(是一个栈结构),例如:

javascript 复制代码
[{name: 'a页面', other: {............}},{name: 'b页面',other: {............}},............]

这种有一个问题,我按顺序记录,我回退一次之后,没有点击前进,而是点了一个其他的页面,那么我需要清空这个页面之后记录的那些数据,很麻烦。

而这种方法,其实浏览器已经实现了,就是第二种方法,路由。

前面说更换路由不行,那就不妨给路由增加query参数。

1.记录当前的页面数据

TypeScript 复制代码
const handleClock = (name: string) => {
  // 正常的点击方法
  // ............
  // 更换路由参数
  router.currentRoute.value.query = {
    name,  
  }
  router.push(router.currentRoute.value)
}

onMounted(() => {
  activeName.value = router.currentRoute.value.query.name || 'init';
})

好的,此时就实现了跟随点击方法来更新路由,并且主路由不变,所以指向的依然是当前页面。

2.使用popstate监听浏览器前进后退点击事件变化

浏览器上有前进后退的点击事件,在JS中表现为 popstate 监听方法。

TypeScript 复制代码
window.addEventListener('popstate', (event: PopStateEvent) => {
    console.log(event);
})

打印一下,结果如下:

state属性中的back、current和forward就是上一个、当前和下一个路由的地址。通过获取这个到这个地址,就可以完成我们的一些相关操作了。

3.使用到的方法

1.router.push和router.replace

这两个方法都可以改变当前的路由地址,并且传参也都是一样的,区别在于,push是往栈里面添加一个数据,replace则是替换掉当前栈里的数据,也就是说replace的操作会导致操作前的路由不被浏览器记录。

TypeScript 复制代码
router.push('/index?a=1');
router.replace('/index?a=1');

router.push({
    query: {
      a: '12',
    },
});
router.replace({
    query: {
      a: '12',
    },
});

router.push(router.currentRoute.value.fullpath)
router.replace(router.currentRoute.value.fullpath)

是不是就看出来push和replace的区别了

2.popstate和pushstate方法

popstate不必多说,前面讲过。但是popstate有一个缺点,就是无法判断当前到底是点的前进还是后退。

当然你可以用变量去记录一下路由地址,然后去和popstate中的参数去对比。

当然也可以使用history内置变量去查看当前路由的一些信息:

也可以使用pushstate方法,来记录当前的点击事件。这个不同于router.push会改变路由,这个是手动的添加一个历史记录到浏览器,但是路由依然是那个路由:

从上面的例子中可以看出,我的路由一直没有变化,但是history中的state会记录当前的历史记录,我们可以通过这个来改变我们想要展示的内容,并且前进。后退、刷新都可以获取到这个历史记录。

个人推荐:改变路由会给用户看到,如果不介意,用push和popstate结合可以实现上述的需求。但是,最好还是使用pushstate和popstate的结合比较好!

相关推荐
jktantan5 小时前
Vue keep-alive 切标签后滚动位置回顶?因为 onDeactivated 里读到的 scrollTop 是 0
前端·javascript·vue.js
总要学点什么5 小时前
第89篇:三维特效-螺旋圆效果——让螺旋臂卷起一圈圈外扩的涟漪
开发语言·javascript·ecmascript·webgl·cesium·空间分析·1024程序员节
2601_962885726 小时前
quotes 字段全解:涨跌幅、振幅、换手率的口径与单位
java·前端·spring
excel6 小时前
encodeURI 和 encodeURIComponent 有什么区别?
前端
前端精髓6 小时前
调用openrouter的免费API模型
java·前端·javascript
赛博守夜人7 小时前
AI安全攻防与治理之十四:AI 安全测试不能脱离传统安全,Web、API、移动端与模型攻击面的组合拳
前端·人工智能·安全
开开心心_Every7 小时前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea
networknomad7 小时前
OpenReplay:自己搭的会话回放工具,给前端排错用的
前端·其他
缓慢更新8 小时前
AI 辅助生成单测:从接口定义到用例的流水线
java·服务器·前端·网络·数据库·人工智能
陈随易8 小时前
AI 运维服务器,安全又可靠的方法
前端·后端·程序员