FxScrollbar 滚动条
用于替换浏览器原生滚动条。不依赖任何 UI 框架,自定义滚动条 + thumb 拖拽。
基础用法
vue
<template>
<FxScrollbar height="400px">
<p v-for="i in 20" :key="i" class="scrollbar-demo-item">{{ i }}</p>
</FxScrollbar>
</template>
<style scoped>
.scrollbar-demo-item {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
margin: 10px;
text-align: center;
border-radius: 4px;
background: color-mix(in srgb, var(--fx-color-primary) 10%, var(--fx-bg-color));
color: var(--fx-color-primary);
}
</style>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
用 height 属性设置滚动条高度;若不设,则根据父容器高度自适应。
横向滚动
vue
<template>
<FxScrollbar>
<div class="scrollbar-flex-content">
<p v-for="i in 50" :key="i" class="scrollbar-demo-item">{{ i }}</p>
</div>
</FxScrollbar>
</template>
<style scoped>
.scrollbar-flex-content {
display: flex;
width: fit-content;
}
.scrollbar-demo-item {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100px;
height: 50px;
margin: 10px;
text-align: center;
border-radius: 4px;
background: color-mix(in srgb, var(--fx-color-danger) 10%, var(--fx-bg-color));
color: var(--fx-color-danger);
}
</style>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
当元素宽度大于滚动条宽度时显示横向滚动条。
最大高度
vue
<template>
<div class="flex gap-3" style="margin-bottom: 12px">
<FxBtn @click="add">Add Item</FxBtn>
<FxBtn @click="onDelete">Delete Item</FxBtn>
</div>
<FxScrollbar max-height="400px">
<p v-for="i in count" :key="i" class="scrollbar-demo-item">{{ i }}</p>
</FxScrollbar>
</template>
<script setup lang="ts">
import { ref } from "vue"
const count = ref(3)
const add = () => {
count.value++
}
const onDelete = () => {
if (count.value > 0) count.value--
}
</script>
<style scoped>
.scrollbar-demo-item {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
margin: 10px;
text-align: center;
border-radius: 4px;
background: color-mix(in srgb, var(--fx-color-primary) 10%, var(--fx-bg-color));
color: var(--fx-color-primary);
}
</style>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
仅当元素高度超过最大高度时才显示滚动条。
手动滚动
vue
<template>
<div style="display: flex; gap: 12px">
<div style="flex: 1">
<FxScrollbar ref="scrollbarRef" height="200px" class="border">
<div style="padding: 12px">
<p v-for="i in 100" :key="i" style="margin: 0 0 8px">item-{{ i }}</p>
</div>
</FxScrollbar>
</div>
<div style="display: flex; flex-direction: column; gap: 8px">
<FxBtn @click="to(0)">到顶部</FxBtn>
<FxBtn @click="to(500)">到 500</FxBtn>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue"
const scrollbarRef = ref()
const to = (val: number) => scrollbarRef.value?.setScrollTop(val)
</script>
<style scoped>
.border {
border: 1px solid var(--fx-border-color);
border-radius: 8px;
}
</style>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
用 setScrollTop 和 setScrollLeft 方法手动控制滚动位置。
无限滚动(end-reached)
vue
<template>
<FxScrollbar height="400px" @end-reached="loadMore">
<p v-for="i in num" :key="i" class="scrollbar-demo-item">{{ i }}</p>
</FxScrollbar>
</template>
<script setup lang="ts">
import { ref } from "vue"
import type { ScrollbarDirection } from "@fx/components"
const num = ref(30)
const loadMore = (direction: ScrollbarDirection) => {
if (direction === "bottom") {
num.value += 5
}
}
</script>
<style scoped>
.scrollbar-demo-item {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
margin: 10px;
text-align: center;
border-radius: 4px;
background: color-mix(in srgb, var(--fx-color-primary) 10%, var(--fx-bg-color));
color: var(--fx-color-primary);
}
</style>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
end-reached 在滚动到底部时触发,可用于无限滚动加载。
API
Attributes
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| height | 滚动条高度 | string / number | — |
| max-height | 滚动条最大高度 | string / number | — |
| native | 是否使用原生滚动条 | boolean | false |
| wrap-style | wrap 容器样式 | string / CSSProperties | — |
| wrap-class | wrap 容器类名 | string | — |
| view-style | view 样式 | string / CSSProperties | — |
| view-class | view 类名 | string | — |
| noresize | 容器尺寸不变时设置以优化性能(不监听 resize) | boolean | false |
| tag | view 的元素标签 | string | div |
| always | 始终显示滚动条 | boolean | false |
| min-size | 滚动条最小尺寸 | number | 20 |
| id | view 的 id | string | — |
| role | view 的 role | string | — |
| aria-label | view 的 aria-label | string | — |
| aria-orientation | view 的 aria-orientation | 'horizontal' | 'vertical' | — |
| tabindex | wrap 的 tabindex | number / string | — |
| distance | 触发 end-reached 的距离(px) | number | 0 |
Events
| 事件名 | 说明 | 类型 |
|---|---|---|
| scroll | 滚动时触发 | ({ scrollLeft: number, scrollTop: number }) => void |
| end-reached | 滚动到达边界时触发 | (direction: 'top' | 'bottom' | 'left' | 'right') => void |
Slots
| 插槽名 | 说明 |
|---|---|
| default | 自定义默认内容 |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| handleScroll | 处理滚动事件 | () => void |
| scrollTo | 滚动到指定坐标 | (options: ScrollToOptions | number, yCoord?: number) => void |
| setScrollTop | 设置垂直滚动距离 | (scrollTop: number) => void |
| setScrollLeft | 设置水平滚动距离 | (scrollLeft: number) => void |
| update | 手动更新滚动条状态 | () => void |
| wrapRef | 滚动容器 wrap 的 ref | Ref<HTMLDivElement> |
