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

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

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

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

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

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

<el-scrollbar
        v-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.kler.cn/a/445333.html

相关文章:

  • 游戏渠道假量解决方案
  • 【Vulkan入门】16-IndexBuffer
  • 从源码分析swift GCD_DispatchGroup
  • 案例分享|企查查的数据降本增效之路
  • uniapp获取内容高度
  • 使用C++构建实战项目:一个简单的任务管理系统
  • 【Linux进程】进程间的通信
  • Dependency Check命令行方式扫描jar包的安全漏洞
  • VMWare 的克隆操作
  • NOTEBOOK_11 汽车电子设备分享(工作经验)
  • 解决小程序中ios可以正常滚动,而Android失效问题
  • pytorch repeat方法和expand方法的区别
  • BigBlueButton视频会议 vs 华为云会议的详细对比
  • Apache Tomcat 漏洞CVE-2024-50379条件竞争文件上传漏洞 servlet readonly spring boot 修复方式
  • VR虚拟展馆如何平衡用户隐私保护与数据收集?
  • django的model中定义【记录修改次数】的这个字段该用什么类型
  • WEB开发: Node.js路由之由浅入深- 即拿即用完整版
  • 12种Vue设计模式
  • 梳理Nginx 的七大应用场景
  • Gin-vue-admin(2):项目创建前端一级页面和二级页面
  • Hadoop、Hbase使用Snappy压缩
  • 十二月第14讲:使用Python实现两组数据纵向排序
  • Go语言启动独立进程
  • DeepSeek-V2的多头潜在注意力机制及其在开源Mixture-of-Experts (MoE)语言模型中的应用
  • 【c++】自定义头文件与CMakeLists.txt添加
  • django 中在admin.py中的管理后台中需要挂载js脚本