vue3 keep-alive跳转回来后 scroll位置丢失
在 Vue3 中,使用 组件确实可以缓存组件状态,避免重复渲染,但它并不直接处理滚动位置的恢复。当页面跳转回来后,如果发现滚动位置scrollTop丢失,可以通过以下方法来解决这个问题:
涉及到在组件的 onBeforeRouteLeave
钩子中保存滚动位置,在 onActivated
钩子中恢复滚动位置。
添加导入
JavaScript 全选
import { ref, onMounted, onActivated } from 'vue';
import { onBeforeRouteLeave } from 'vue-router';
在 Vue3 中,onBeforeRouteLeave
是 Vue Router
的导航守卫,而不是 Vue 本身的生命周期钩子。因此,你需要从 vue-router 中导入它,而不是从 vue。
逻辑实现
JavaScript 全选
// 保存的滚动位置
let savedScrollTop = 0;
const scrollContainer = ref(null);
onActivated(() => {
// 从 keep-alive 缓存中恢复时,恢复滚动位置
console.log('onActivated savedScrollTop == ', savedScrollTop)
if (savedScrollTop > 0) {
scrollContainer.value.scrollTop = savedScrollTop;
}
});
onBeforeRouteLeave(() => {
// 保存滚动位置到路由元信息
savedScrollTop = scrollContainer.value.scrollTop
console.log('onBeforeRouteLeave savedScrollTop == ', savedScrollTop)
});
编写为自定义指令,方便使用
vue3 + javascript:src/directives/saveScrollTop.js
C# 全选
// import router from '@/router'
import { onBeforeRouteLeave } from 'vue-router'
export default {
name: 'saveScrollTop',
savedScrollTop: 0,
// 在绑定元素的 attribute 前
// 或事件监听器应用前调用
created(el, binding, vnode, prevVnode) {
// 下面会介绍各个参数的细节
console.log('v-saveScrollTop created')
},
// 在元素被插入到 DOM 前调用
beforeMount(el, binding, vnode, prevVnode) {
console.log('v-saveScrollTop beforeMount')
},
// 在绑定元素的父组件
// 及他自己的所有子节点都挂载完成后调用
mounted(el, binding, vnode, prevVnode) {
console.log('v-saveScrollTop mounted')
// onBeforeRouteLeave(() => {
// // 保存滚动位置到路由元信息
// binding.dir.savedScrollTop = el.scrollTop
// console.log('onBeforeRouteLeave savedScrollTop == ', binding.dir.savedScrollTop)
// })
el.__scrollHandler = () => {
binding.dir.savedScrollTop = el.scrollTop
console.log('v-saveScrollTop savedScrollTop == ', binding.dir.savedScrollTop)
}
el.addEventListener('scroll', el.__scrollHandler)
},
// 绑定元素的父组件更新前调用
beforeUpdate(el, binding, vnode, prevVnode) {
console.log('v-saveScrollTop beforeUpdate')
},
// 在绑定元素的父组件
// 及他自己的所有子节点都更新后调用
updated(el, binding, vnode, prevVnode) {
console.log('v-saveScrollTop updated')
console.log('onActivated savedScrollTop == ', binding.dir.savedScrollTop)
if (binding.dir.savedScrollTop > 0) {
el.scrollTop = binding.dir.savedScrollTop
}
},
// 绑定元素的父组件卸载前调用
beforeUnmount(el, binding, vnode, prevVnode) {
console.log('v-saveScrollTop beforeUnmount')
el.removeEventListener('scroll', el.__scrollHandler)
},
// 绑定元素的父组件卸载后调用
unmounted(el, binding, vnode, prevVnode) {
console.log('v-saveScrollTop unmounted')
}
}
main.js中注册指令
JavaScript 全选
import saveScrollTop from './directives/saveScrollTop'
const app = createApp(App)
// 注册全局指令
app.directive(saveScrollTop.name, saveScrollTop)
使用:
在需要保存滚动位置的元素中,使用指令 v-saveScrollTop
版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
post 张国生