[Vue3] 实现滚动条自动恢复位置的hook

1,416 阅读1分钟

一、需求背景

在一个后台管理的项目中,多tab页签切换时使用keep-alive进行了页签内容的缓存;从页签A切换到页签B,再切回页签A时,页签A内部的滚动条会重置在起始位置;现在想要实现,切换到页签A时,滚动条能恢复上次离开页签A时的位置。

二、实现

  1. hook代码
import type { Ref } from 'vue'

export function useScrollRecover(el: Ref<HTMLElement | undefined>) {
    // 用于记录滚动位置的变量
    const scrollTop = ref(0)
    
    // 滚动响应处理函数,在事件中记录滚动位置
    const onScroll = () => {
      scrollTop.value = unref(el)?.scrollTop || 0
    }
    
    // mounted时监听scroll事件
    onMounted(() => {
      unref(el)?.addEventListener('scroll', onScroll)
    })
    
    // keep-alive激活时会自动调用actived钩子,此时将容器的滚动高度设置为记录的值
    onActivated(() => {
      if (unref(el))
        (unref(el) as HTMLElement).scrollTop = unref(scrollTop)
    })
    
    // unmounted时记得取消监听
    onUnmounted(() => {
      unref(el)?.removeEventListener('scroll', onScroll)
    })
  }

  1. hook使用
<template>
    <div ref='containerRef'>
     这是一个滚动容器
    </div>
</template>

<script>
const containerRef = ref<HTMLElement>()

useScrollRecover(containerRef)
</script>

三、总结

使用hook的方式封装之后,使用非常方便,且代码易于维护。