Skip to content

Instantly share code, notes, and snippets.

@TimRChen
Last active December 2, 2022 06:34
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TimRChen/d121f9ef99236752cf7bbc98852bba1e to your computer and use it in GitHub Desktop.
Save TimRChen/d121f9ef99236752cf7bbc98852bba1e to your computer and use it in GitHub Desktop.
vue 3 pc浏览器 infinite scroll hook - useInfiniteScroll
import { unref, isRef, Ref, onUnmounted } from 'vue'
type IntersectTarget = Element | Ref
/**
* 采用Intersection Observer API 实现无限滚动
* more_help: https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API#intersection_observer_%E7%9A%84%E6%A6%82%E5%BF%B5%E5%92%8C%E7%94%A8%E6%B3%95
* @author <timrchen@foxmail.com>
* @param target 目标元素,可在可增加列表末尾设置一个标志标签
* @param callback 正在相交时执行回调,请注意!如果有一些耗时的操作需要执行,建议使用 Window.requestIdleCallback() 方法
* @param options IntersectionObserver()构造函数的 options 对象,可选值参考:https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver/IntersectionObserver#%E5%8F%82%E6%95%B0
*/
export default function useInfiniteScroll(
callback: () => void,
options: IntersectionObserverInit = {},
target: IntersectTarget,
) {
const executor = ([entry]: IntersectionObserverEntry[]) => {
// 目标元素是否进入可视区域
if (entry && entry.isIntersecting) callback()
}
const observer = new IntersectionObserver(executor, options)
const intersectTarget: Element = isRef(target) ? unref(target) : target
observer.observe(intersectTarget)
onUnmounted(() => observer && observer.disconnect())
}
@TimRChen
Copy link
Author

用法非常简单,这里贴一下使用代码:

    const listData = ref([])
    const callback = async () => {
      const list = unref(listData)
      const newList = await fetchList()
      listData.value = [...list, ...newList]
    }

    onMounted(() => {
      const root = document.querySelector('.list-body')
      const target = document.querySelector('.intersect-point') as Element
      const options: IntersectionObserverInit = { root, rootMargin: '24px' }
      useInfiniteScroll(callback, options, target)
    })

@TimRChen
Copy link
Author

在主流浏览器中可广泛使用Intersection Observer API,性能占优,且简单易用。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment