滚动条 ScrollBar
像素风格的滚动条组件,基于 OverlayScrollbars。
滚动容器
使用 ScrollBar 组件,把内容装在滚动条里。使用时可能需要设置高度样式。
传入 scrollOffset 作为滚动条偏移量。传入 scrollOffset 进入受控模式。不传或者为 undefined 则为非受控模式,此时可以传入 defaultScrollOffset 属性作为默认值。
scrollOffset 的更新是带有防抖的,只会在停止滚动时触发。如果需要监听滚动,可以监听 scroll 事件。
对于 ScrollBar 组件,获取它的 DOM 元素后,可以像原生元素那样,访问 scrollBy、scrollTo、scrollTop、scrollLeft 等属性。
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take arms against a sea of troubles
And by opposing end them. To die—to sleep,
No more; and by a sleep to say we end
The heart-ache and the thousand natural shocks
That flesh is heir to: 'tis a consummation
Devoutly to be wish'd. To die, to sleep;
To sleep, perchance to dream—ay, there's the rub:
For in that sleep of death what dreams may come,
When we have shuffled off this mortal coil,
Must give us pause—there's the respect
That makes calamity of so long life.
<template>
<px-space direction="vertical">
<div>scrollOffset: {{ scrollOffset }}</div>
<px-scroll-bar
v-model:scroll-offset="scrollOffset"
style="height: 200px"
@scroll="scrollHandler"
>
To be, or not to be, that is the question:<br />
Whether 'tis nobler in the mind to suffer<br />
The slings and arrows of outrageous fortune,<br />
Or to take arms against a sea of troubles<br />
And by opposing end them. To die—to sleep,<br />
No more; and by a sleep to say we end<br />
The heart-ache and the thousand natural shocks<br />
That flesh is heir to: 'tis a consummation<br />
Devoutly to be wish'd. To die, to sleep;<br />
To sleep, perchance to dream—ay, there's the rub:<br />
For in that sleep of death what dreams may come,<br />
When we have shuffled off this mortal coil,<br />
Must give us pause—there's the respect<br />
That makes calamity of so long life.
</px-scroll-bar>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const scrollOffset = ref({ left: 0, top: 0 })
const scrollHandler = (e: Event) => {
console.log((e.target as Element).scrollLeft, (e.target as Element).scrollTop)
}
</script>滚动条样式
滚动条目前有 2 种样式变体,像素风格('pixel',默认)和简单模式('simple'),通过 variant 设置。
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
Loooooooooooooooong text
<template>
<px-space direction="vertical">
<px-radio-group v-model="variant" :options="options"></px-radio-group>
<px-scroll-bar style="height: 200px" :variant="variant">
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
Loooooooooooooooong text<br />
</px-scroll-bar>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const variant = ref('pixel')
const options = [
{
label: 'Pixel',
value: 'pixel'
},
{
label: 'Simple',
value: 'simple'
}
]
</script>函数式
使用 useScrollBar 钩子,手动为某个区域加上像素风滚动条。为需要加上滚动条的元素添加属性 data-overlayscrollbars-initialize 防止滚动条闪烁问题的出现。
And now I'll do't. And so he goes to heaven;
And so am I revenged. That would be scann'd:
A villain kills my father; and for that,
I, his sole son, do this same villain send
To heaven.
O, this is hire and salary, not revenge.
He took my father grossly, full of bread;
With all his crimes broad blown, as flush as May;
And how his audit stands who knows save heaven?
But in our circumstance and course of thought,
'Tis heavy with him: and am I then revenged,
To take him in the purging of his soul,
When he is fit and season'd for his passage?
No!
Up, sword; and know thou a more horrid bent:
When he is drunk asleep, or in his rage,
Or in the incestuous pleasure of his bed;
At gaming, swearing, or about some act
That has no relish of salvation in't;
Then trip him, that his heels may kick at heaven,
And that his soul may be as damn'd and black
As hell, whereto it goes. My mother stays:
This physic but prolongs thy sickly days.
<template>
<px-space direction="vertical">
<span> Scroll bar ready ? {{ initialized }} </span>
<div style="height: 200px" ref="targetRef" data-overlayscrollbars-initialize>
Now might I do it pat, now he is praying;<br />
And now I'll do't. And so he goes to heaven;<br />
And so am I revenged. That would be scann'd:<br />
A villain kills my father; and for that,<br />
I, his sole son, do this same villain send<br />
To heaven.<br />
O, this is hire and salary, not revenge.<br />
He took my father grossly, full of bread;<br />
With all his crimes broad blown, as flush as May;<br />
And how his audit stands who knows save heaven?<br />
But in our circumstance and course of thought,<br />
'Tis heavy with him: and am I then revenged,<br />
To take him in the purging of his soul,<br />
When he is fit and season'd for his passage?<br />
No!<br />
Up, sword; and know thou a more horrid bent:<br />
When he is drunk asleep, or in his rage,<br />
Or in the incestuous pleasure of his bed;<br />
At gaming, swearing, or about some act<br />
That has no relish of salvation in't;<br />
Then trip him, that his heels may kick at heaven,<br />
And that his soul may be as damn'd and black<br />
As hell, whereto it goes. My mother stays:<br />
This physic but prolongs thy sickly days.
</div>
</px-space>
</template>
<script lang="ts" setup>
import { useScrollBar } from '@pixelium/web-vue'
// If on-demand import
// import { useScrollBar } from '@pixelium/web-vue/es'
import { onMounted, shallowRef } from 'vue'
const [init, getInstance, initialized] = useScrollBar()
const targetRef = shallowRef<HTMLDivElement | null>(null)
onMounted(() => {
if (!targetRef.value) {
return
}
init({
target: targetRef.value
})
})
</script>这样子可以为 <body> 元素加上滚动条。此时也可以正常访问 window.scrollX、window.scrollY、window.scroll、window.scrollTo、window.scrollBy 等原生属性。
为了防止闪烁,请为 <html> 和 <body> 加上 data-overlayscrollbars-initialize 属性。
import { useScrollBar } from '@pixelium/web-vue'
// If on-demand import
// import { useScrollBar } from '@pixelium/web-vue/es'
const [init] = useScrollBar()
init({
target: document.body
})2
3
4
5
6
7
8
9
10
API
如果不能满足你的需求,可以前往 OverlayScrollbars 文档查看使用方法。
像素风滚动条的主题名为 'px-scroll-theme'(对应variant="pixel")和 'px-scroll-simple-theme'(对应variant="simple")。导入全量的样式,或者手动导入 @pixelium/web-vue/es/scroll-bar/index.css 后,你就可以在 OverlayScrollbars 上使用它。
ScrollBarProps
| 属性 | 类型 | 可选 | 默认值 | 描述 | 版本 |
|---|---|---|---|---|---|
| scrollOffset | { left?: number; top?: number } | null | 是 | | 滚动的偏移量,受控模式,支持 v-model。 | 0.1.0 |
| defaultScrollOffset | { left?: number; top?: number } | null | 是 | | 滚动的偏移量默认值,非受控模式。 | 0.1.0 |
| variant | 'pixel' | 'simple' | 是 | 'pixel' | 滚动的样式变体。 | 0.1.0 |
| showScrollPadding | boolean | 是 | true | 是否在滚动条出现一侧增加 padding。 | 0.1.0 |
ScrollBarEvents
| 事件 | 参数 | 描述 | 版本 |
|---|---|---|---|
| update:scrollOffset | value: { left: number; top: number } | 更新 scrollOffset 的回调。 | 0.1.0 |
| initialize | instance: OverlayScrollbars | 滚动条初始化的回调。接收 OverlayScrollbars 实例作为入参,具体参数见 OverlayScrollbars 文档。 | 0.1.0 |
| update | | 滚动条触发更新的回调。 | 0.1.0 |
| scroll | event: Event | 滚动时的回调。 | 0.1.0 |
ScrollBarSlots
| 插槽 | 参数 | 描述 | 版本 |
|---|---|---|---|
| default | | 滚动容器内容。 | 0.1.0 |
ScrollBarExpose
| 属性 | 类型 | 可选 | 默认值 | 描述 | 版本 |
|---|---|---|---|---|---|
| scrollTo | { (options?: ScrollToOptions): void; (x: number, y: number): void } | 否 | | 效果同原生 scrollTo。 | 0.1.0 |
| scrollBy | { (options?: ScrollToOptions): void; (x: number, y: number): void } | 否 | | 效果同原生 scrollBy。 | 0.1.0 |
useScrollBar
import { type UseOverlayScrollbarsInitialization, type UseOverlayScrollbarsInstance } from 'overlayscrollbars-vue'
const useScrollBar: (variant?: "pixel" | "simple") => readonly [UseOverlayScrollbarsInitialization, UseOverlayScrollbarsInstance, Ref<boolean, boolean>]2
3