From 2c43a14e38e6cb188d115435ef99b1b1b9f8055b Mon Sep 17 00:00:00 2001 From: renyt Date: Fri, 9 May 2025 11:05:18 +0800 Subject: [PATCH] 1 --- pages/index/index.vue | 2074 +++++++++++++++++++++++++++++++++++++++++ pages/index/utils.js | 79 ++ 2 files changed, 2153 insertions(+) create mode 100644 pages/index/index.vue create mode 100644 pages/index/utils.js diff --git a/pages/index/index.vue b/pages/index/index.vue new file mode 100644 index 0000000..ece85f2 --- /dev/null +++ b/pages/index/index.vue @@ -0,0 +1,2074 @@ + + + + + \ No newline at end of file diff --git a/pages/index/utils.js b/pages/index/utils.js new file mode 100644 index 0000000..2715f00 --- /dev/null +++ b/pages/index/utils.js @@ -0,0 +1,79 @@ +import { ref, onMounted, onUnmounted } from 'vue' + +export function useElementSize(targetSelector) { + const width = ref(0) + const height = ref(0) + let observer = null + + const updateSize = () => { + const query = uni.createSelectorQuery() + query.select(targetSelector).boundingClientRect(rect => { + if (rect) { + width.value = rect.width + height.value = rect.height + } + }).exec() + } + + onMounted(() => { + updateSize() + // 尝试使用 ResizeObserver(部分小程序基础库支持) + if (uni.createIntersectionObserver) { + observer = uni.createIntersectionObserver(this, { + observeAll: true + }) + observer.relativeToViewport().observe(targetSelector, updateSize) + } + }) + + onUnmounted(() => { + observer?.disconnect() + }) + + return { width, height, updateSize } +} + +export function useEventListener(target, event, handler) { + // 组件内事件 + if (target.$on) { + target.$on(event, handler) + const stop = () => target.$off(event, handler) + onUnmounted(stop) + return stop + } + // 全局事件(需配合 uni.$emit 使用) + else { + uni.$on(event, handler) + const stop = () => uni.$off(event, handler) + onUnmounted(stop) + return stop + } +} + + +export function useRafFn(fn, { immediate = true } = {}) { + let isActive = false + let timerId = null + + const loop = () => { + if (!isActive) return + fn() + timerId = setTimeout(loop, 16) // 模拟 60fps + } + + const start = () => { + if (isActive) return + isActive = true + loop() + } + + const stop = () => { + isActive = false + clearTimeout(timerId) + } + + onUnmounted(stop) + immediate && start() + + return { start, stop } +} \ No newline at end of file