跳到主要内容

useScroll

分类
导出大小
2.22 kB
上次更改
4 个月前

响应式滚动位置和状态。

演示

左上角
左下角
右上角
右下角
滚动我
X 坐标
Y 坐标
测量
isScrollingfalse
到达顶部
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>

带偏移量

ts
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 })

重新计算滚动状态

您可以随时调用 measure() 方法手动更新滚动位置和 arrivedState

这在例如动态内容更改后或您想在滚动事件之外重新计算滚动状态时非常有用。

ts
import { 
useScroll
} from '@vueuse/core'
import {
nextTick
,
onMounted
,
useTemplateRef
,
watch
} from 'vue'
const
el
=
useTemplateRef
<HTMLElement>('el')
const
reactiveValue
=
shallowRef
(false)
const {
measure
} =
useScroll
(
el
)
// In a watcher
watch
(
reactiveValue
, () => {
measure
()
}) // Or inside any function function
updateScrollState
() {
// ...some logic
nextTick
(() => {
measure
()
}) }
js
import { useScroll } from '@vueuse/core'
import { nextTick, useTemplateRef, watch } from 'vue'
const el = useTemplateRef('el')
const reactiveValue = shallowRef(false)
const { measure } = useScroll(el)
// In a watcher
watch(reactiveValue, () => {
  measure()
})
// Or inside any function
function updateScrollState() {
  // ...some logic
  nextTick(() => {
    measure()
  })
}

注意

建议在 nextTick() 内调用 measure(),以确保 DOM 首先更新。滚动状态会在 onMount 时自动初始化。只有在动态更改后需要重新计算状态时,才需要手动调用 measure()

指令用法

此函数还通过 @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-scrol
l="
onScroll
">
<
div
v-for="
item
in
data
"
:key
="
item
">
{{
item
}}
</
div
>
</
div
>
<!-- with options --> <
div
v-scrol
l="
[
onScroll
, {
throttle
: 10 }]
">
<
div
v-for="
item
in
data
"
:key
="
item
">
{{
item
}}
</
div
>
</
div
>
</template>

类型声明

显示类型声明
ts
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
} /** * Use MutationObserver to monitor specific DOM changes, * such as attribute modifications, child node additions or removals, or subtree changes. * @default { mutation: boolean } */
observe
?:
| boolean | {
mutation
?: boolean
} /** * 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
NoiseFan
IlyaL
SerKo
Andy Luo
Mateusz Kołodziej
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

更新日志

8c521 - feat(components)!: 重构组件并使其保持一致 (#4912)
v13.4.0
135d5 - fix: 使用 mutationObserver 在 DOM 更改时更新 arrivedState (#4433)
v12.8.0
7432f - feat(types): 废弃 MaybeRefMaybeRefOrGetter,转而使用 Vue 的原生类型 (#4636)
4b7ab - fix: 处理负滚动值 (#4613)
v12.3.0
59f75 - feat(toValue): 废弃 @vueuse/shared 中的 toValue,转而使用 Vue 的原生函数
a033e - feat(useWindowScroll): 在底层使用 useScroll (#4424)
v12.1.0
90ff4 - fix: 为弹性滚动正确报告 arriveState (#4133)
0a9ed - feat!: 放弃对 Vue 2 的支持,优化打包并清理 (#4349)
317ca - fix: 将滚动值同步到内部状态,修复 #3809 (#3817)
v10.8.0
fab86 - fix: 添加 onError 钩子并默认避免抛出异常,修复 #3580 (#3605)
v10.6.1
e9742 - fix: 无法读取 null 的属性 (读取文档) (#3544)
v10.6.0
86bd8 - fix: onMounted 时触发一次以获取正确的初始 arrivedStates 值 (#3384)
v10.4.0
c1b29 - fix: 规避 window 或 document 是 Proxy 的边缘情况 (#3280)
v10.3.0
dde41 - fix: 支持可配置的 window (#3229)
v10.2.0
8855f - fix: 在 setArrivedState 中支持 window (#3086)
v10.1.1
a88fe - fix(useInfiniteScroll): 当异步无限滚动解析时重新测量到达状态 (#3030)

根据 MIT 许可证发布。