2024-11-05 10:09:18 +08:00

66 lines
1.6 KiB
TypeScript

import { getCurrentInstance } from 'vue'
import { debugWarn } from '../../utils'
import type { ComponentInternalInstance } from 'vue'
export interface ObserverFnOptions {
type: 'relativeTo' | 'relativeToViewport'
selector?: string
margins: {
top?: number
right?: number
bottom?: number
left?: number
}
}
export const useObserver = (instance?: ComponentInternalInstance | null) => {
if (!instance) {
instance = getCurrentInstance()
}
// #ifdef H5 | APP-PLUS
instance = instance?.proxy?.$parent as ComponentInternalInstance | null
// #endif
if (!instance) {
debugWarn('useObserver', '请在 setup 中使用 useObserver')
}
// Observer对象
let observerInstance: UniApp.IntersectionObserver | null = null
const connectObserver = (
selector: string,
fn: (res: UniApp.ObserveResult) => void,
fnOptions: ObserverFnOptions,
options?: UniApp.CreateIntersectionObserverOptions
) => {
// 开始监听布局之前先停止旧的监听
disconnectObserver()
observerInstance = uni.createIntersectionObserver(instance, options)
if (fnOptions.type === 'relativeTo')
observerInstance.relativeTo(fnOptions?.selector || '', fnOptions.margins)
else if (fnOptions.type === 'relativeToViewport')
observerInstance.relativeToViewport(fnOptions.margins)
observerInstance.observe(selector, (res) => {
fn && fn(res)
})
}
// 停止监听布局状态
const disconnectObserver = () => {
if (observerInstance) {
observerInstance.disconnect()
observerInstance = null
}
}
return {
connectObserver,
disconnectObserver,
}
}