vue下拉加载页面切换回到当前滚动位置

server/2024/12/23 23:52:48/

当项目是下拉分页加载数据时,当离开页面再次回到当前页面时,数据会从第一页重新加载,这就会造成不好的体验。所以解决办法就是在离开当前页面时记录当前滚动的位置,然后再下次回到当前页面时,跳转到当前记录的位置。触底下拉加载可看下面这篇帖子:

el-scrollbar实现触底加载数据_el-scrollbar触底事件-CSDN博客

用el-scrollbar组件时,需要记录滚动的位置,需要用到scroll事件,然后通过scrollTop,因为

通过ref属性是拿不到滚动位置,所以需要通过scroll事件来记录每次滚动的位置。

<el-scrollbarv-if="state.list.length"ref="scroll"class="scrollBox"@scroll="handleScroll">
</el-scrollbar>// 记录当前滚动的位置
const handleScroll = (event: any) => {state.scrollPosition = event.scrollTop;
}

然后再离开页面时将当前滚动位置存到缓存中,但是如果有多个页面都需要记录的话,就需要区分存储的名字来进行区分,这里用到的是拼接当前路由的name属性,不会存在重复的问题。

值得注意的是:在vue页面中,一般离开页面时在事件onBeforeUnmount进行处理,但因为要拼接路由的name,在onBeforeUnmount生命周期中,拿到的name属性是跳转到新页面的name属性,而不是当前页面的,所以需要用到onBeforeRouteLeave,可以拿到当前页面的name属性来进行下一步操作。比如:

onBeforeRouteLeave(() => {if (scroll.value) {const name = route.name as string;sessionStorage.setItem(`scrollPosition-${name}`, state.scrollPosition + "");}
});

然后再进入页面时获取当前页面存储的滚动位置。然后进行跳转。这就需要用到scrollTo属性。

if (scroll.value) {const name = route.name as string;const scrollPosition =sessionStorage.getItem(`scrollPosition-${name}`) || "0";scroll.value.scrollTo({ top: scrollPosition });
}

但是会有一个衍生问题,如果加载了多页数据,也记录了当前滚动的位置,但当重新回到当前页面的时候,它只能跳到最底部,然后加载下一页的数据,并不能达到回到离开页面时记录的位置。所以这就需要下一步的操作,将数据和当前页数存储到store中,进入页面时,先从store中拉取数据和当前应该开始的页数,如果没有则拉取数据,否则就用store中存储的数据,就可以解决这一问题。

但当页面刷新时,store中的数据就会清空,但是当前页面存储的滚动位置还是在缓存中存在的,所以还会进行距离滚动。理想状态应该是页面刷新时,回到最顶部,这里解决方案就有很多,记录一下我的解决方法,用到的是监听浏览器刷新,然后刷新时,清空掉自己存储的滚动位置。

// 获取所有的缓存,然后遍历自己存储时的特殊开头,然后清空掉所有存储的滚动位置
const removeItemsWithPrefix = (prefix: any) => {// 遍历 sessionStorage 中所有的键for (let i = 0; i < sessionStorage.length; i++) {const key = sessionStorage.key(i) as any; // 获取当前的键if (key.startsWith(prefix)) {// 判断该键是否以指定的前缀开头sessionStorage.removeItem(key); // 移除该项}}
};
// "scrollPosition-"  这就是存储时所用的特殊标识
const handleBeforeUnload = () => {removeItemsWithPrefix("scrollPosition-");
};

下面是监听页面刷新和卸载监听的事件。

onBeforeUnmount(() => {window.removeEventListener("beforeunload", handleBeforeUnload);
});
onMounted(async () => {window.addEventListener("beforeunload", handleBeforeUnload);
}


http://www.ppmy.cn/server/152612.html

相关文章

【Python使用】嘿马头条项目从到完整开发教程第9篇:缓存,1 缓存穿透【附代码文档】

本教程的知识点为:简介 1. 内容 2. 目标 产品效果 ToutiaoWeb虚拟机使用说明 数据库 理解ORM 作用 思考&#xff1a; 使用ORM的方式选择 数据库 SQLAlchemy操作 1 新增 2 查询 all() 数据库 分布式ID 1 方案选择 2 头条 使用雪花算法 &#xff08;代码 toutiao-backend/common/…

HTMLCSS:这个动态删除按钮打几分?

这段HTML和CSS代码创建了一个可交互的按钮&#xff0c;该按钮在鼠标悬停时会展开显示一个删除图标和文字标签 演示效果 HTML&CSS <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-U…

ubuntu 如何重装你的apt【apt-get报错: symbol lookup error/undefined symbol】

副标题:解决error:apt-get: symbol lookup error: /lib/x86_64-linux-gnu/libapt-private.so.0.0: undefined symbol: _ZNK13pkgTagSection7FindULLENS_3KeyERKy, version APTPKG_6.0 文章目录 问题描述报错分析解决方案:重装你的apt1、查看你的ubuntu版本2、下载适配你的ap…

elementui在任意页面点击消息,弹出消息对应页面处理弹窗

需求&#xff1a;在系统的任意页面点击消息都能弹出对应页面中的操作弹窗 思路&#xff1a; 1、创建一个全局组件&#xff0c;这个组件要能在任何地方都被打开&#xff08;所以放在了app.vue页面&#xff09; 2、使用component 组件找到要打开的页面路径 3、在被打开的页面中…

大数据新视界 -- Hive 数据仓库:架构深度剖析与核心组件详解(上)(1 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

ExcelVBA编程输出ColorIndex与对应颜色色谱

标题 ExcelVBA编程输出ColorIndex与对应颜色色谱 正文 解决问题编程输出ColorIndex与对应色谱共56&#xff0c;打算分4纵列输出&#xff0c;标题是ColorIndex,Color,Name 1. 解释VBA中的ColorIndex属性 在VBA&#xff08;Visual Basic for Applications&#xff09;中&#xff…

虚拟机VMware的安装问题ip错误,虚拟网卡

要么没有虚拟网卡、有网卡远程连不上等 一般出现在win11 家庭版 1、是否IP错误 ip addr 2、 重置虚拟网卡 3、查看是否有虚拟网卡 4、如果以上检查都解决不了问题 如果你之前有vmware 后来卸载了&#xff0c;又重新安装&#xff0c;一般都会有问题 卸载重装vmware: 第一…

【Java计算机毕业设计】基于Springboot小药店销售管理系统【源代码+数据库+LW文档+开题报告+答辩稿+部署教程+代码讲解】

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…