跳到内容

useScroll

类别
导出大小
1.79 kB
上次更改
5 天前

响应式的滚动位置和状态。

演示

左上
左下
右上
右下
滚动我
X 轴位置
Y 轴位置
正在滚动false
到达顶部
true
到达右侧
false
到达底部
false
到达左侧
true
向上滚动
false
向右滚动
false
向下滚动
false
向左滚动
false

用法

vue
<script setup lang="ts">
import { useScroll } from '@vueuse/core'
import { useTemplateRef } from 'vue'

const el = useTemplateRef<HTMLElement>('el')
const { x, y, isScrolling, arrivedState, directions } = useScroll(el)
</script>

<template>
  <div ref="el" />
</template>

带偏移量

js
const { x, y, isScrolling, arrivedState, directions } = useScroll(el, {
  offset: { top: 30, bottom: 30, right: 30, left: 30 },
})

设置滚动位置

设置 xy 值以使元素滚动到该位置。

vue
<script setup lang="ts">
import { useScroll } from '@vueuse/core'
import { useTemplateRef } from 'vue'

const el = useTemplateRef<HTMLElement>('el')
const { x, y } = useScroll(el)
</script>

<template>
  <div ref="el" />
  <button @click="x += 10">
    Scroll right 10px
  </button>
  <button @click="y += 10">
    Scroll down 10px
  </button>
</template>

平滑滚动

设置 behavior: smooth 以启用平滑滚动。behavior 选项默认为 auto,这意味着不进行平滑滚动。有关更多信息,请参阅 window.scrollTo() 上的 behavior 选项。

ts
import { useScroll } from '@vueuse/core'
import { useTemplateRef } from 'vue'

const el = useTemplateRef<HTMLElement>('el')
const { x, y } = useScroll(el, { behavior: 'smooth' })

// Or as a `ref`:
const smooth = ref(false)
const behavior = computed(() => smooth.value ? 'smooth' : 'auto')
const { x, y } = useScroll(el, { behavior })
js
import { useScroll } from '@vueuse/core'
import { useTemplateRef } from 'vue'
const el = useTemplateRef('el')
const { x, y } = useScroll(el, { behavior: 'smooth' })
// Or as a `ref`:
const smooth = ref(false)
const behavior = computed(() => (smooth.value ? 'smooth' : 'auto'))
const { x, y } = useScroll(el, { behavior })

指令用法

此函数还通过 @vueuse/components 包提供指令版本。 了解更多关于用法的信息

vue
<script setup lang="ts">
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-scroll="onScroll">
    <div v-for="item in data" :key="item">
      {{ item }}
    </div>
  </div>

  <!-- with options -->
  <div v-scroll="[onScroll, { throttle: 10 }]">
    <div v-for="item in data" :key="item">
      {{ item }}
    </div>
  </div>
</template>

类型声明

显示类型声明
typescript
export interface UseScrollOptions extends ConfigurableWindow {
  /**
   * Throttle time for scroll event, it’s disabled by default.
   *
   * @default 0
   */
  throttle?: number
  /**
   * The check time when scrolling ends.
   * This configuration will be setting to (throttle + idle) when the `throttle` is configured.
   *
   * @default 200
   */
  idle?: number
  /**
   * Offset arrived states by x pixels
   *
   */
  offset?: {
    left?: number
    right?: number
    top?: number
    bottom?: number
  }
  /**
   * Trigger it when scrolling.
   *
   */
  onScroll?: (e: Event) => void
  /**
   * Trigger it when scrolling ends.
   *
   */
  onStop?: (e: Event) => void
  /**
   * Listener options for scroll event.
   *
   * @default {capture: false, passive: true}
   */
  eventListenerOptions?: boolean | AddEventListenerOptions
  /**
   * Optionally specify a scroll behavior of `auto` (default, not smooth scrolling) or
   * `smooth` (for smooth scrolling) which takes effect when changing the `x` or `y` refs.
   *
   * @default 'auto'
   */
  behavior?: MaybeRefOrGetter<ScrollBehavior>
  /**
   * On error callback
   *
   * Default log error to `console.error`
   */
  onError?: (error: unknown) => void
}
/**
 * Reactive scroll.
 *
 * @see https://vueuse.org.cn/useScroll
 * @param element
 * @param options
 */
export declare function useScroll(
  element: MaybeRefOrGetter<
    HTMLElement | SVGElement | Window | Document | null | undefined
  >,
  options?: UseScrollOptions,
): {
  x: WritableComputedRef<number, number>
  y: WritableComputedRef<number, number>
  isScrolling: ShallowRef<boolean, boolean>
  arrivedState: {
    left: boolean
    right: boolean
    top: boolean
    bottom: boolean
  }
  directions: {
    left: boolean
    right: boolean
    top: boolean
    bottom: boolean
  }
  measure(): void
}
export type UseScrollReturn = ReturnType<typeof useScroll>

源代码

源代码演示文档

贡献者

Anthony Fu
Anthony Fu
IlyaL
webfansplz
kongmoumou
Curt Grimes
Robin
719media
Dima Kaltovich
Poet
Nico Prat
MinatoHikari
Vladimir
AlanYu
Scott Bedard
Christian Martinez
丶远方
holtergram
Ayaka Rizumu
云游君
btea
Thierry Michel
Pavel Yankovski
Bobakanoosh
Joseph Fitz Hughes

更新日志

v12.8.0 于 2025/3/5
7432f - feat(types): 弃用 MaybeRefMaybeRefOrGetter,转而使用 Vue 的原生类型 (#4636)
4b7ab - fix: 处理负滚动值 (#4613)
v12.3.0 于 2025/1/2
59f75 - feat(toValue): 弃用 @vueuse/shared 中的 toValue,转而使用 Vue 的原生类型
a033e - feat(useWindowScroll): 底层使用 useScroll (#4424)
v12.1.0 于 2024/12/22
90ff4 - fix: 正确报告弹性滚动的 arriveState (#4133)
v12.0.0-beta.1 于 2024/11/21
0a9ed - feat!: 移除 Vue 2 支持,优化捆绑包并清理 (#4349)
v10.10.0 于 2024/5/27
317ca - fix: 同步滚动值到内部状态,修复 #3809 (#3817)
v10.8.0 于 2024/2/20
fab86 - fix: 添加 onError 钩子并避免默认抛出错误,修复 #3580 (#3605)
v10.6.1 于 2023/11/13
e9742 - fix: 无法读取 null 的属性 (读取 document) (#3544)
v10.6.0 于 2023/11/9
86bd8 - fix: 触发一次 onMounted 以获取正确的初始 arrivedStates 值 (#3384)
v10.4.0 于 2023/8/25
c1b29 - fix: 避开 window 或 document 是 Proxy 的极端情况 (#3280)
v10.3.0 于 2023/7/30
dde41 - fix: 支持可配置的 window (#3229)
v10.2.0 于 2023/6/16
8855f - fix: 在 setArrivedState 中支持 window (#3086)
v10.1.1 于 2023/5/1
a88fe - fix(useInfiniteScroll): 当异步无限滚动解决时,重新测量到达状态 (#3030)
v10.0.0-beta.4 于 2023/4/13
23b9a - fix: 添加对 row-reverse 和 column-reverse 的支持 (#2577)
4d757 - feat(types)!: 将 MaybeComputedRef 重命名为 MaybeRefOrGetter
0a72b - feat(toValue): 将 resolveUnref 重命名为 toValue
v9.13.0 于 2023/2/18
f8872 - feat: 支持 scrollend 事件 (#2716)

在 MIT 许可证下发布。