尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

airi × VueUse useIntersectionObserver 实战:元素可见性监听的 Composable、指令与类型声明详解

airi × VueUse useIntersectionObserver 实战:元素可见性监听的 Composable、指令与类型声明详解 airi × VueUse useIntersectionObserver 实战元素可见性监听的 Composable、指令与类型声明详解【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi在 airi 这类以 Vue 3 TypeScript 构建、大量依赖 VueUse 可复用组合式函数的项目工作区通过 pnpm-workspace.yaml 的 catalog 统一锁定vueuse/core^14.4.0中元素何时进入视口是懒加载、滚动动画、曝光统计等场景的基础能力。本文围绕仓库内的技能参考文档 useIntersectionObserver.md 展开完整讲解useIntersectionObserver的 Composable 用法、v-intersection-observer指令用法、全部配置参数与类型声明并结合 airi 仓库中真实使用原生IntersectionObserver的场景说明其落地价值。核心定位它是做什么的useIntersectionObserver属于 VueUse 的Elements分类见 SKILL.md 中 Elements 表格核心职责一句话概括检测目标元素可见性的变化Detects changes to a target elements visibility。它是对浏览器原生IntersectionObserverAPI 的响应式封装把元素是否/多可见这一异步的、事件驱动的检测结果变成可以驱动 Vue 响应式状态ref的数据源并自动处理生命周期清理。Composable 用法监听模板 ref 并驱动响应式状态文档给出的标准用法如下注意 Vue 3.5 中useTemplateRef替代了getCurrentInstance().refs取法script setup langts import { useIntersectionObserver } from vueuse/core import { shallowRef, useTemplateRef } from vue const target useTemplateRef(target) const targetIsVisible shallowRef(false) const { stop } useIntersectionObserver( target, ([entry], observerElement) { targetIsVisible.value entry?.isIntersecting || false }, ) /script template div reftarget h1Hello world/h1 /div /template要点解析第一个参数target接收useTemplateRef(target)的结果。从类型声明看它支持三种形态MaybeComputedElementRef单个响应式元素引用、MaybeRefOrGetterMaybeElement[]元素数组的 ref/getter、或两者的数组——也就是说它可以一次监听多个元素甚至监听集合本身动态变化的元素。第二个参数callback就是原生IntersectionObserverCallback签名是(entries, observer) void。回调里解构取entries[0]用entry.isIntersecting布尔值是否相交判定可见性entry上还带有intersectionRatio相交比例、boundingClientRect、rootBounds、time等字段可用于更精细的逻辑。返回值解构出stop用于手动停止观察composable 在组件卸载时会自动清理一般无需手动调用stop除非你希望在卸载前就释放观察器。targetIsVisible用shallowRef而非ref是刻意选择它只存一个布尔值shallowRef能避免不必要的深层代理开销——这在频繁触发快速滚动时是更稳妥的写法。Directive 用法v-intersection-observer 指令如果不想在script setup里写完整的 composableVueUse 提供了vueuse/components中的vIntersectionObserver指令直接在模板里绑定回调script setup langts import { vIntersectionObserver } from vueuse/components import { shallowRef, useTemplateRef } from vue const root useTemplateRef(root) const isVisible shallowRef(false) function onIntersectionObserver([entry]: IntersectionObserverEntry[]) { isVisible.value entry?.isIntersecting || false } /script template div p Scroll me down! /p div v-intersection-observeronIntersectionObserver pHello world!/p /div /div !-- with options -- div refroot p Scroll me down! /p div v-intersection-observer[onIntersectionObserver, { root }] pHello world!/p /div /div /template指令绑定值有两种写法仅回调v-intersection-observeronIntersectionObserver默认以 viewport 为根、threshold: 0回调 选项对象v-intersection-observer[onIntersectionObserver, { root }]第二个元素即UseIntersectionObserverOptions上例把root指向另一个容器表示以该容器的边界而非浏览器视口为参照系来判断相交——这是做容器内滚动曝光检测的关键参数。配置参数与类型声明完整继承文档给出了完整的类型声明这里逐字段展开其含义与取值export interface UseIntersectionObserverOptions extends ConfigurableWindow { /** * Start the IntersectionObserver immediately on creation * default true */ immediate?: boolean /** * The Element or Document whose bounds are used as the bounding box when testing for intersection. */ root?: MaybeComputedElementRef | Document /** * A string which specifies a set of offsets to add to the roots bounding_box when calculating intersections. */ rootMargin?: MaybeRefOrGetterstring /** * Either a single number or an array of numbers between 0.0 and 1. * default 0 */ threshold?: number | number[] } export interface UseIntersectionObserverReturn extends Supportable, Pausable { stop: () void } export declare function useIntersectionObserver( target: | MaybeComputedElementRef | MaybeRefOrGetterMaybeElement[] | MaybeComputedElementRef[], callback: IntersectionObserverCallback, options?: UseIntersectionObserverOptions, ): UseIntersectionObserverReturn参数速查表参数类型默认值说明immediatebooleantrue创建时是否立即启动观察。设为false可实现按需启动/暂停返回值含Pausable可与isActive联动rootMaybeComputedElementRef \| Documentviewport作为判定参照的滚动容器。传一个容器元素后相交检测以该容器边界为准适用于容器内滚动场景rootMarginMaybeRefOrGetterstring0px参照边界外的偏移语法与 CSS 的margin相同如100px 0px常用来做提前 100px 触发的懒加载或预热thresholdnumber \| number[]00.0–1.0 之间的单个数或数组表示触发回调所需的最小相交比例。数组如[0.25, 0.5, 0.75]会在每个比例跨越时都触发回调windowWindow继承自ConfigurableWindow当前 window指定观察器所在的窗口对象SSR 环境下可指向defaultWindow以避免访问不存在的 DOM返回对象继承Supportable含isSupportedSSR 下为false、Pausable含isActive并额外暴露stop()手动停止。几个值得注意的设计root与rootMargin均为响应式类型MaybeComputedElementRef/MaybeRefOrGetter意味着可以把一个 ref 传进去当容器元素在异步渲染后才挂载、或偏移量随布局动态变化时composable 内部会unref并跟随变化无需重建 observer。immediate: false 返回值Pausable可以把监听挂起配合其它状态如元素尚未创建、页面被锁定在合适时机再激活。isSupported在 SSRNuxt SSR 渲染阶段该值为falsecomposable 会安全地不执行浏览器 API因此这段代码在 SSR 项目中可以无条件使用。在 airi 仓库中的印证原生 IntersectionObserver 的典型场景当前仓库源码中没有直接以useIntersectionObserver命名的调用技能文档.agents/skills/vueuse-functions是作为 Agent 开发指南随仓维护的参考集但用 IntersectionObserver 做可见性驱动这一模式在 airi 的文档站组件里有真实落地ThemedVideo.vue 中手动new IntersectionObserver(handleVisibility, {...})第 31–58 行附近在视频进入视口时恢复播放、离开时暂停——这正是useIntersectionObserver抽象所覆盖的场景。对比一下两条路径原生写法ThemedVideo.vue 的做法需要自己保存observer引用、在onBeforeUnmount中手动disconnect()、处理组件复用与元素替换useIntersectionObserver写法生命周期清理、响应式 target、SSR 守卫都由 composable 承担回调里只需要写可见时做什么。从源码结构看airi 的 stage-web、stage-ui 等包均已依赖vueuse/core/vueuse/shared见 apps/stage-web/package.json、packages/stage-ui/package.json因此任何需要元素进出视口驱动行为的组件都可以按本文模式直接使用而无需新增依赖。典型实战映射需求推荐配置图片/组件懒加载提前于视口加载rootMargin: 200px 0px回调中当entry.isIntersecting为 true 时加载资源并可考虑加载后stop()曝光/统计进入视口才计数threshold: 0.5保证元素至少 50% 可见才记一次滚动进度/分段动画threshold: [0.1, 0.25, 0.5, 0.75, 0.9]在回调中读取entry.intersectionRatio驱动样式容器内滚动检测如侧边栏、虚拟列表视口root指向容器 ref配合rootMargin收窄/扩大触发区暂停/恢复监听immediate: false 返回值isActive控制或调用stop()小结useIntersectionObserver的价值在于把原生IntersectionObserver的三件麻烦事——异步回调、生命周期清理、SSR 兼容——收敛为一个接收响应式 target 的 composable。掌握threshold/root/rootMargin/immediate四个参数再配合 Composable 与v-intersection-observer指令两种接入方式就能在 airi 这类 VueUse 深度集成的项目中覆盖绝大多数元素可见性需求。进一步的 API 语义可对照文档末尾指向的浏览器标准IntersectionObserver接口以及 SKILL.md 中同属 Elements 分类的useElementVisibility仅追踪视口内可见性、useResizeObserver尺寸变化等邻近能力做选型。【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表