UNPKG

tdesign-mobile-vue

Version:
1 lines 9.24 kB
{"version":3,"file":"useResizeObserver.mjs","sources":["../../src/hooks/useResizeObserver.ts"],"sourcesContent":["import { ref, Ref, onMounted, onUnmounted, watch, unref } from 'vue';\n\nexport interface UseResizeObserverOptions {\n /**\n * 是否在尺寸从 0 变为非 0 时触发回调(用于处理 v-show 场景)\n * @default false\n */\n onVisibilityChange?: boolean;\n /**\n * 是否在任何尺寸变化时都触发回调\n * @default true\n */\n onResize?: boolean;\n /**\n * 是否立即开始观察\n * @default true\n */\n immediate?: boolean;\n}\n\nexport interface ResizeCallbackParams {\n width: number;\n height: number;\n entry: ResizeObserverEntry;\n /** 是否是从不可见变为可见(尺寸从 0 变为非 0) */\n becameVisible: boolean;\n}\n\nexport type ResizeCallback = (params: ResizeCallbackParams) => void;\n\n/**\n * 通用的 ResizeObserver hook\n * 支持监听元素尺寸变化,以及元素从不可见变为可见(v-show 场景)\n *\n * @param target 目标元素或 Ref\n * @param callback 尺寸变化时的回调函数\n * @param options 配置选项\n *\n * @example\n * // 基础用法 - 监听尺寸变化\n * useResizeObserver(elementRef, ({ width, height }) => {\n * console.log('尺寸变化:', width, height);\n * });\n *\n * @example\n * // 只监听可见性变化(v-show 场景)\n * useResizeObserver(elementRef, ({ becameVisible }) => {\n * if (becameVisible) {\n * console.log('元素变为可见');\n * }\n * }, { onVisibilityChange: true, onResize: false });\n *\n * @example\n * // 同时监听尺寸变化和可见性变化\n * useResizeObserver(elementRef, ({ width, height, becameVisible }) => {\n * if (becameVisible) {\n * // 元素从隐藏变为可见,重新初始化\n * initComponent();\n * }\n * }, { onVisibilityChange: true });\n */\nexport function useResizeObserver(\n target: Ref<HTMLElement | null | undefined> | HTMLElement | null | undefined,\n callback: ResizeCallback,\n options: UseResizeObserverOptions = {},\n) {\n const { onVisibilityChange = false, onResize = true, immediate = true } = options;\n\n const isSupported = typeof ResizeObserver !== 'undefined';\n const previousSize = ref({ width: 0, height: 0 });\n let observer: ResizeObserver | null = null;\n\n const cleanup = () => {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n };\n\n const observe = () => {\n cleanup();\n\n const element = unref(target);\n if (!element || !isSupported) return;\n\n // 初始化 previousSize\n previousSize.value = {\n width: element.offsetWidth || 0,\n height: element.offsetHeight || 0,\n };\n\n observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect;\n const { width: prevWidth, height: prevHeight } = previousSize.value;\n\n // 检测是否从不可见变为可见(宽度或高度从 0 变为非 0)\n const wasHidden = prevWidth === 0 || prevHeight === 0;\n const isVisible = width > 0 && height > 0;\n const becameVisible = wasHidden && isVisible;\n\n // 检测尺寸是否发生变化\n const sizeChanged = width !== prevWidth || height !== prevHeight;\n\n // 更新记录的尺寸\n previousSize.value = { width, height };\n\n // 根据配置决定是否触发回调\n const shouldTrigger = (onVisibilityChange && becameVisible) || (onResize && sizeChanged && !becameVisible);\n\n if (shouldTrigger) {\n callback({\n width,\n height,\n entry,\n becameVisible,\n });\n }\n }\n });\n\n observer.observe(element);\n };\n\n // 监听 target 变化\n if (typeof target === 'object' && target !== null && 'value' in target) {\n watch(\n () => unref(target),\n (newEl, oldEl) => {\n if (newEl !== oldEl) {\n observe();\n }\n },\n { flush: 'post' },\n );\n }\n\n onMounted(() => {\n if (immediate) {\n observe();\n }\n });\n\n onUnmounted(() => {\n cleanup();\n });\n\n return {\n /** 是否支持 ResizeObserver */\n isSupported,\n /** 手动停止观察 */\n stop: cleanup,\n /** 手动开始观察 */\n start: observe,\n };\n}\n\n/**\n * 监听元素从不可见变为可见(专门用于 v-show 场景)\n *\n * @param target 目标元素或 Ref\n * @param callback 元素变为可见时的回调\n *\n * @example\n * useVisibilityObserver(elementRef, () => {\n * // 元素变为可见,重新计算布局\n * updateLayout();\n * });\n */\nexport function useVisibilityObserver(\n target: Ref<HTMLElement | null | undefined> | HTMLElement | null | undefined,\n callback: () => void,\n) {\n return useResizeObserver(\n target,\n ({ becameVisible }) => {\n if (becameVisible) {\n callback();\n }\n },\n { onVisibilityChange: true, onResize: false },\n );\n}\n\nexport default useResizeObserver;\n"],"names":["useResizeObserver","target","callback","options","arguments","length","undefined","_options$onVisibility","onVisibilityChange","_options$onResize","onResize","_options$immediate","immediate","isSupported","ResizeObserver","previousSize","ref","width","height","observer","cleanup","disconnect","observe","element","unref","value","offsetWidth","offsetHeight","entries","_iterator","_createForOfIteratorHelper","_step","s","n","done","entry","_entry$contentRect","contentRect","_previousSize$value","prevWidth","prevHeight","wasHidden","isVisible","becameVisible","sizeChanged","shouldTrigger","err","e","f","_typeof","watch","newEl","oldEl","flush","onMounted","onUnmounted","stop","start","useVisibilityObserver","_ref"],"mappings":"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"}