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

vue3+ts实现页面滚动位置的保存及恢复

vue3+ts实现页面滚动位置的保存及恢复

前言:

折腾了n个小时才搞定,这个在vue2中不显眼的功能到了vue3中没想到成为了拦路虎。借助于AI一遍一遍的尝试各种方案,最终敲定了路由scrollBehavior保存组件滚动位置到pinia,页面的onActivated中读取滚动位置并进行恢复。

关键代码:

1. 编写store保存页面滚动位置:

scrollStore.ts

import { defineStore, createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";// 第一步:创建 Pinia 实例
const pinia = createPinia();
// 第二步:注册持久化插件(必须在定义 Store 之前)
pinia.use(piniaPluginPersistedstate);
// 第三步:导出pinia
export default pinia;//页面滚动状态保持
export const useScrollStore = defineStore("scrollStore", {state: () => {return {scrollTop: 0,};},//数据持久化配置
  persist: {storage: sessionStorage,},actions: {updateScrollTop(data) {console.log(data);this.scrollTop = data;},},
});

2. 使用scrollBehavior保存滚动位置到store中:

router.ts

import { createRouter, createWebHashHistory } from "vue-router";
import { useScrollStore } from "@/store/index";const routerHash = createWebHashHistory();const router = createRouter({history: routerHash,routes: [{path: "/",name: "Home",meta: {keepAlive: true,saveScroll: true,},component: () => import("@/views/Home.vue"),},{path: "/:w+",name: "Error",meta: {title: "访问错误",},component: () => import("@/views/Error.vue"),},], // 关键:覆盖默认滚动行为,阻止路由切换时自动滚顶scrollBehavior: (to, from, savedPosition) => {// 1. 若从需要保存滚动的页面(from.meta.saveScroll)跳转,优先恢复滚动if (to.meta.saveScroll) {const scrollStore = useScrollStore();const savedTop = scrollStore.scrollTop;if (savedTop > 0) {// 用 nextTick 确保 DOM 已渲染,比 setTimeout(0) 更快return nextTick().then(() => {const container = document.getElementById("container");if (container) {return {el: "#container", // 指定滚动容器top: savedTop, // 恢复到保存的位置behavior: "smooth", // 默认为瞬间滚动(无动画,避免闪动)
            };}});}}// 2. 其他页面默认滚顶(可根据需求调整)return { top: 0 };},
});
export default router;

3. 页面引入:
需要保持页面滚动位置的页面只需引入 useScroll,无需额外代码

<template><div id="container"><!--页面内容--></div>
</template><script setup lang="ts">import { useScroll} from '@/store/useScroll'useScroll()</script><style lang="scss" scoped>#container {height: calc(100vh - 100px);overflow-y: scroll;}
</style>

如上,即可实现页面滚动位置保存及恢复功能,实测有效,如果遇到没生效的可以留言代码交流。