尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

airi 前端工程中的 VueUse useScroll 实战指南:响应式滚动位置与滚动状态全解析

发布时间:2026/9/10 13:56:09

资讯中心
01
ARTICLE

airi 前端工程中的 VueUse useScroll 实战指南:响应式滚动位置与滚动状态全解析

airi 前端工程中的 VueUse useScroll 实战指南:响应式滚动位置与滚动状态全解析
airi 前端工程中的 VueUse useScroll 实战指南响应式滚动位置与滚动状态全解析【免费下载链接】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/airiuseScroll是 VueUse 提供的响应式滚动组合式函数composable它以一行代码将任意 DOM 元素、Window或Document的滚动位置x/y、滚动状态isScrolling、到达边界状态arrivedState与滚动方向directions全部变为 Vue 响应式数据。本文以 .agents/skills/vueuse-functions/references/useScroll.md 为骨架结合 airi 仓库中vueuse/core的实际应用与滚动相关源码实现完整讲解其 API、配置项、指令用法与典型落地场景读完后你可以直接在 Vue 3 组件中实现滚动监听、锚点定位、无限滚动、返回顶部等能力而无需手写任何事件绑定与清理逻辑。useScroll 是什么Sensors 分类下的响应式滚动传感器在 airi 仓库的 .agents/skills/vueuse-functions/SKILL.md 中useScroll被归类在Sensors传感器分类下官方描述为 Reactive scroll position and state响应式滚动位置与状态调用规则为AUTO——即只要需求涉及滚动位置与状态的响应式跟踪就应优先考虑使用它而不是手写addEventListener(scroll)。整个 airi 仓库是一个横跨 Webapps/stage-web、移动端apps/stage-pocket、桌面端apps/stage-tamagotchi的多端 Vue 3 工程其下几乎所有前端子包的package.json都声明了vueuse/core依赖例如 apps/stage-web/package.json、packages/stage-ui/package.json、packages/stage-layouts/package.json、packages/ui/package.json 等。这意味着useScroll的能力在整个工程的 UI 层随处可用是编写简洁、可维护滚动逻辑的首选工具。基本用法从元素到响应式状态useScroll接受一个可变的元素引用MaybeRefOrGetter支持HTMLElement、SVGElement、Window、Document或null。最常见的写法是配合 Vue 3.5 的useTemplateRef获取模板元素script setup langts import { useScroll } from vueuse/core import { useTemplateRef } from vue const el useTemplateRef(el) const { x, y, isScrolling, arrivedState, directions } useScroll(el) /script template div refel / /template这段代码做了四件事x/y当前滚动位置像素是WritableComputedRefnumber既可读也可写isScrollingShallowRefboolean是否正在滚动arrivedState包含left/right/top/bottom四个布尔值分别表示是否已滚动到对应边界directions包含同样四个布尔值表示最近一次滚动的方向。配合watch或模板中的条件渲染即可实现滚动到容器底部时加载更多吸顶导航显示/隐藏回到顶部按钮等常见交互。配置偏移量arrivedState 的提前触发默认情况下arrivedState在完全贴住边界时才为true。通过offset选项可以指定距边界多少像素就算到达非常适合需要提前触发加载的场景import { useScroll } from vueuse/core const { x, y, isScrolling, arrivedState, directions } useScroll(el, { offset: { top: 30, bottom: 30, right: 30, left: 30 }, })offset支持left、right、top、bottom四个方向的独立配置单位均为像素。例如在移动端列表页设置{ bottom: 50 }后当用户滚到距底部 50px 时arrivedState.bottom即变为true可据此触发分页请求实现丝滑的无限滚动体验。双向绑定通过修改 x / y 编程式滚动x与y是WritableComputedRef直接赋值即可让元素滚动到指定位置不需要调用任何原生 APIscript setup langts import { useScroll } from vueuse/core import { useTemplateRef } from vue const el useTemplateRef(el) const { x, y } useScroll(el) /script template div refel / button clickx 10 Scroll right 10px /button button clicky 10 Scroll down 10px /button /template这个特性使滚动位置天然成为应用状态的一部分你可以把x/y直接交给computed、watch甚至持久化到useStorage实现记住用户上次阅读位置之类的功能。平滑滚动behavior 选项与动态切换behavior选项控制修改x/y时的滚动行为默认值为auto即不平滑、瞬间跳转可设为smooth启用平滑滚动语义与浏览器原生window.scrollTo()的behavior参数一致import { useScroll } from vueuse/core import { useTemplateRef } from vue const el useTemplateRef(el) const { x, y } useScroll(el, { behavior: smooth }) // 也可以传 ref / computed实现动态切换 const smooth ref(false) const behavior computed(() smooth.value ? smooth : auto) const { x, y } useScroll(el, { behavior })注意behavior的类型是MaybeRefOrGetterScrollBehavior即可以传普通字符串、ref或 getter 函数。利用这一点你可以把是否平滑滚动与用户偏好设置如系统prefers-reduced-motion或应用内开关绑定动态改变滚动体验。手动重算滚动状态measure()useScroll在组件onMount时自动初始化一次滚动状态并在滚动事件期间持续更新。但某些动态内容变化如列表异步加载后高度变化不会触发 scroll 事件此时可以调用返回的measure()手动重算位置与arrivedStateimport { useScroll } from vueuse/core import { nextTick, onMounted, useTemplateRef, watch } from vue const el useTemplateRef(el) const reactiveValue shallowRef(false) const { measure } useScroll(el) // 在 watcher 中 watch(reactiveValue, () { measure() }) // 或在任意函数中 function updateScrollState() { // ...some logic nextTick(() { measure() }) }使用上有三个关键注意点官方建议在nextTick()内调用measure()确保 DOM 更新完成后再读取滚动状态滚动状态会在onMount时自动初始化不需要在挂载阶段手动调用只有当动态变化导致 scroll 事件无法覆盖状态更新时才需要手动调用measure()。指令用法vScroll 免样板监听如果不想在script setup中显式创建 refVueUse 还提供了基于指令directive的用法vScroll来自vueuse/components。它把UseScrollReturn状态整体作为回调参数传入script setup langts import type { UseScrollReturn } from vueuse/core import { vScroll } from vueuse/components const data ref([1, 2, 3, 4, 5, 6]) function onScroll(state: UseScrollReturn) { console.log(state) // {x, y, isScrolling, arrivedState, directions} } /script template div v-scrollonScroll div v-foritem in data :keyitem {{ item }} /div /div !-- 带选项第二个元素为 UseScrollOptions -- div v-scroll[onScroll, { throttle: 10 }] div v-foritem in data :keyitem {{ item }} /div /div /templatev-scroll的值可以是一个回调函数也可以是一个[回调, 选项]元组。这种形式特别适合列表、卡片流等批量滚动容器省去了为每个容器单独写 ref 和事件监听的样板代码。完整类型声明UseScrollOptions 与 UseScrollReturn原文档给出了完整的 TypeScript 类型声明理解它们是精准使用useScroll的前提export interface UseScrollOptions extends ConfigurableWindow { /** * 滚动事件的节流时间默认禁用。 * * default 0 */ throttle?: number /** * 判定滚动结束的检查时间。 * 当配置了 throttle 时该值会被设置为 (throttle idle)。 * * default 200 */ idle?: number /** * 按像素偏移到达边界状态 */ offset?: { left?: number right?: number top?: number bottom?: number } /** * 使用 MutationObserver 监听特定 DOM 变化 * 如属性修改、子节点增删或子树变化。 * default { mutation: boolean } */ observe?: | boolean | { mutation?: boolean } /** * 滚动过程中触发。 */ onScroll?: (e: Event) void /** * 滚动结束时触发。 */ onStop?: (e: Event) void /** * scroll 事件的监听选项。 * * default {capture: false, passive: true} */ eventListenerOptions?: boolean | AddEventListenerOptions /** * 修改 x/y refs 时的滚动行为 * auto默认不平滑或 smooth平滑滚动。 * * default auto */ behavior?: MaybeRefOrGetterScrollBehavior /** * 错误回调。 * * 默认通过 console.error 输出错误。 */ onError?: (error: unknown) void } export interface UseScrollReturn { x: WritableComputedRefnumber y: WritableComputedRefnumber isScrolling: ShallowRefboolean arrivedState: { left: boolean right: boolean top: boolean bottom: boolean } directions: { left: boolean right: boolean top: boolean bottom: boolean } measure: () void } /** * Reactive scroll. * * param element * param options */ export declare function useScroll( element: MaybeRefOrGetter HTMLElement | SVGElement | Window | Document | null | undefined , options?: UseScrollOptions, ): UseScrollReturn逐项解读几个容易忽略的选项throttle默认 0对 scroll 事件做节流。高频滚动场景如 parallax 视差、滚动进度条建议设置可显著降低计算频率idle默认 200ms滚动停止判定时间。内部在最后一次 scroll 事件后等待idle毫秒才将isScrolling置为false并触发onStop。当配置了throttle时实际等待时间自动变为throttle idleobserve默认启用基于MutationObserver的 DOM 变化监听默认值为{ mutation: boolean }形态能感知内容增删引起的高度变化弥补纯 scroll 事件的盲区若性能敏感可显式关闭onScroll/onStop滚动中与滚动结束时的回调钩子适合做滚动结束后保存位置到后端之类的收尾操作eventListenerOptions默认{capture: false, passive: true}原生监听器选项。passive: true意味着监听器不会调用preventDefault()浏览器可跳过布局计算保证滚动帧率onError错误回调默认行为是输出到console.error。在 airi 工程中的落地结合与 useScrollToHash 的互补关系虽然仓库中没有直接调用useScroll(的业务代码但其自定义的滚动定位组合式函数 packages/stage-ui/src/composables/use-scroll-to-hash.ts 与useScroll的思路高度互补可作为理解本库应用的参照它同样接受behavior选项默认为smooth并通过window.scrollTo({ top, behavior })或容器元素的container.scrollTo({ top, behavior })实现平滑锚点定位语义与useScroll的behavior完全一致它支持scrollContainer自定义滚动容器默认window这与useScroll可接收任意滚动元素含Window的设计理念一脉相承它实现了目标元素未找到时自动重试默认最多 10 次、间隔 100ms以及新滚动开始时取消旧的重试循环恰好覆盖了useScroll需要结合measure()手动重算的那类动态 DOM 场景。实际开发中可以组合使用用useScroll跟踪滚动位置与到达底部状态如聊天消息面板触底自动加载历史记录用useScrollToHash处理路由锚点跳转。airi 是一个支持实时语音对话、包含大量长列表与多页面跳转的多端应用Web / macOS / Windows这类滚动状态 锚点定位的组合正是其 UI 层的常见需求。小结useScroll用极小的 API 面覆盖了滚动场景的绝大多数诉求位置读写x/y、滚动中状态isScrolling、边界状态arrivedState、方向检测directions以及手动重算measure配合throttle、idle、observe、offset、behavior等细粒度选项足以替代手写的事件监听样板。在 airi 这类大量使用vueuse/core的多端 Vue 工程中遇到任何响应式滚动需求都应优先查阅 .agents/skills/vueuse-functions/references/useScroll.md 并按AUTO规则直接采用必要时与仓库内已有的 use-scroll-to-hash.ts 等自定义组合式函数搭配即可构建出简洁、高性能、可维护的滚动交互。【免费下载链接】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),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。