new IntersectionObserver js方法描述步驟
實現邏輯:通過監視底部節點可視情況,獲取新數據進行渲染,如果獲取不到最新數據則顯示暫無其他數據
new IntersectionObserver 是用于監視元素可見度,所以我們只需要監視數據下方的dom是否可見
import { type Ref, watchEffect, ref } from "vue"//我用的ts,不需要可以刪除
interface IntersectionObserverProps {target: Ref<Element | null | undefined>root?: Ref<any>onIntersect: IntersectionObserverCallbackrootMargin?: stringthreshold?: number | number[]
}export function useIntersectionObserver({ target, root, onIntersect, rootMargin = "0px", threshold = 0.1 }: IntersectionObserverProps) {let cleanup: Function//每次調用前先移除監聽const observer: Ref<Nullable<IntersectionObserver>> = ref(null)const stopEffect = watchEffect(() => {cleanup && cleanup()observer.value = new IntersectionObserver(onIntersect, {root: root ? root.value : null,//設置監視器的根節點,不傳則默認為視口rootMargin,//類似于 CSS 的 margin 屬性。用來縮小或擴大 rootBounds,從而影響相交的觸發。threshold/*屬性決定相交比例為多少時,觸發回調函數。取值為 0 ~ 1,或者 0 ~ 1的數組。當我們把 threshold 設置為 [0, 0.25, 0.5, 0.75, 1],元素分別在 0%,25%,50%,75%,100% 可見時,觸發回調函數。*/})const current = target.value//被監視的元素本身current && observer.value.observe(current)// 開始觀察某個目標元素cleanup = () => {if (observer.value) {observer.value.disconnect()// 關閉監視器target.value && observer.value.unobserve(target.value)// 停止觀察某個目標元素}}})//將方法暴露出來外部也可使用return {observer,stop: () => {cleanup()stopEffect()}}
}
不清楚方法配置項的可以看MDN Intersection Observer
組件中使用
將暫無其他數據的dom給到方法去監視
這里我只是簡單演示方法,監視效果達后到可以自行更改ui和觸底后的邏輯
html:
<div v-for='item in data' key='item' >{{item}}</div>
<div ref="empty">{{"暫無其他數據" }}</div>
js部分
const empty = ref(null)
// 默認在初始創建節點時會觸發一次,因為初始沒有數據節點會在視圖中完整呈現,也可以讓節點在有數據的時候再創建
const { stop, observer } = useIntersectionObserver({target: empty,//最底部的domonIntersect: (entries: any[]) => {//isIntersecting:boolean 表示節點是否可見,intersectionRatio:number 表示節點可見度數值const isIntersecting = entries[0].isIntersecting || entries[0].intersectionRatioif (!isIntersecting) return... //此處寫要實現的邏輯},threshold: 0.1//為1 表示dom完整呈現
})
如果需要詳細講解可以看這兩篇文章:
https://juejin.cn/post/6844903927419256846
https://juejin.cn/post/6950464500491354126#heading-9
也可以去MDN Intersection Observer 查看完整配置項和方法
vue基于組合式API提供的@vueuse/core插件內的useIntersectionObserver
安裝
npm i @vueuse/core
使用
useIntersectionObserver其實就是方便了我們之前封裝的那個步驟,如果想要基于這個二次封裝也是可以的
// 封裝一個通用的方法實現數據的懶加載
import { useIntersectionObserver } from '@vueuse/core'
import { ref } from 'vue'export const useLazyData = (apiFn) => {// target表示組件的最外層div元素const target = ref(null)// 懶加載接口返回的數據const result = ref([])// 監聽組件是否進入可視區const { stop } = useIntersectionObserver(target, ([{ isIntersecting }]) => {// 如果target對應的DOM進入可視區,那么該回調函數就觸發if (isIntersecting) {// 被監聽的DOM進入了可視區:此時調用接口獲取數據;停止繼續監聽stop()... //此處寫要實現的邏輯}})// result表示接口懶加載獲取的業務數據// target表示被監聽的DOM元素,需要在模板中被ref屬性綁定return { result, target }
}