滑块
特性
- 可受控或非受控。
- 支持多个滑块手柄。
- 支持滑块手柄之间的最小间隔值。
- 支持通过触摸或点击轨道来更新值。
- 支持从右到左方向。
- 完整的键盘导航功能。
安装
从命令行安装此组件。
$ npm add reka-ui
结构
导入所有部分并将其组合。
<script setup>
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'reka-ui'
</script>
<template>
<SliderRoot>
<SliderTrack>
<SliderRange />
</SliderTrack>
<SliderThumb />
</SliderRoot>
</template>
API 参考
根组件
包含滑块的所有部分。当在 form
中使用时,它将为每个滑块手柄渲染一个 input
元素,以确保事件正确传播。
属性 | 默认 | 类型 |
---|---|---|
as | 'span' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
defaultValue | [0] | number[] 滑块初始渲染时的值。当您不需要控制滑块状态时使用。 |
dir | 'ltr' | 'rtl' 适用时,组合框的阅读方向。 | |
disabled | false | 布尔值 当为 |
inverted | false | 布尔值 滑块是否在视觉上反向显示。 |
max | 100 | 数字 范围的最大值。 |
min | 0 | 数字 范围的最小值。 |
minStepsBetweenThumbs | 0 | 数字 多个滑块手柄之间允许的最小步长。 |
modelValue | number[] | null 滑块的受控值。可绑定为 | |
name | string 字段的名称。随其所属的表单一起作为名称/值对提交。 | |
orientation | 'horizontal' | 'vertical' | 'horizontal' 滑块的方向。 |
required | 布尔值 当为 | |
step | 1 | 数字 步长间隔。 |
thumbAlignment | 'contain' | 'contain' | 'overflow' 滑块手柄的对齐方式。
|
事件触发 | 载荷 |
---|---|
update:modelValue | [payload: number[]] 滑块值改变时调用的事件处理函数 |
valueCommit | [payload: number[]] 交互结束时值改变时调用的事件处理函数。 当您只需捕获最终值(例如更新后端服务)时很有用。 |
插槽(默认) | 载荷 |
---|---|
modelValue | number[] | null 当前滑块值 |
数据属性 | 值 |
---|---|
[data-disabled] | 禁用时存在 |
[data-orientation] | "垂直" | "水平" |
轨道
包含 SliderRange
的轨道。
属性 | 默认 | 类型 |
---|---|---|
as | 'span' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
数据属性 | 值 |
---|---|
[data-disabled] | 禁用时存在 |
[data-orientation] | "垂直" | "水平" |
范围
范围部分。必须位于 SliderTrack
内部。
属性 | 默认 | 类型 |
---|---|---|
as | 'span' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
数据属性 | 值 |
---|---|
[data-disabled] | 禁用时存在 |
[data-orientation] | "垂直" | "水平" |
滑块手柄
一个可拖动的滑块手柄。您可以渲染多个手柄。
属性 | 默认 | 类型 |
---|---|---|
as | 'span' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
数据属性 | 值 |
---|---|
[data-disabled] | 禁用时存在 |
[data-orientation] | "垂直" | "水平" |
示例
垂直方向
使用 orientation
属性来创建垂直滑块。
// index.vue
<script setup>
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'reka-ui'
</script>
<template>
<SliderRoot
class="SliderRoot"
:default-value="[50]"
orientation="vertical"
>
<SliderTrack class="SliderTrack">
<SliderRange class="SliderRange" />
</SliderTrack>
<SliderThumb class="SliderThumb" />
</SliderRoot>
</template>
/* styles.css */
.SliderRoot {
position: relative;
display: flex;
align-items: center;
}
.SliderRoot[data-orientation="vertical"] {
flex-direction: column;
width: 20px;
height: 100px;
}
.SliderTrack {
position: relative;
flex-grow: 1;
background-color: grey;
}
.SliderTrack[data-orientation="vertical"] {
width: 3px;
}
.SliderRange {
position: absolute;
background-color: black;
}
.SliderRange[data-orientation="vertical"] {
width: 100%;
}
.SliderThumb {
display: block;
width: 20px;
height: 20px;
background-color: black;
}
创建范围
添加多个滑块手柄和值以创建范围滑块。
// index.vue
<script setup>
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'reka-ui'
</script>
<template>
<SliderRoot :default-value="[25, 75]">
<SliderTrack>
<SliderRange />
</SliderTrack>
<SliderThumb />
<SliderThumb />
</SliderRoot>
</template>
定义步长
使用 step
属性来增加步长间隔。
// index.vue
<script setup>
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'reka-ui'
</script>
<template>
<SliderRoot
:default-value="[50]"
:step="10"
>
<SliderTrack>
<SliderRange />
</SliderTrack>
<SliderThumb />
</SliderRoot>
</template>
防止滑块手柄重叠
使用 minStepsBetweenThumbs
以避免滑块手柄的值相等。
// index.vue
<script setup>
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'reka-ui'
</script>
<template>
<SliderRoot
:default-value="[25, 75]"
:step="10"
:min-steps-between-thumbs="1"
>
<SliderTrack>
<SliderRange />
</SliderTrack>
<SliderThumb />
<SliderThumb />
</SliderRoot>
</template>
可访问性
遵循 滑块 WAI-ARIA 设计模式。
键盘交互
键 | 描述 |
---|---|
向右箭头 | 按 step 量增加值。 |
向左箭头 | 按 step 量减小值。 |
向上箭头键 | 按 step 量增加值。 |
向下箭头键 | 按 step 量减小值。 |
PageUp (上翻页) | 按更大的 step 量增加值。 |
PageDown (下翻页) | 按更大的 step 量减小值。 |
Shift + 向上箭头 | 按更大的 step 量增加值。 |
Shift + 向下箭头 | 按更大的 step 量减小值。 |
Home (回到开头) | 将值设置为最小值。 |
End (回到末尾) | 将值设置为最大值。 |
反向滑块
当滑块为时,某些控件也会反向,具体取决于.
- 当滑块为(默认),向右箭头、向左箭头、Home 和 End 会反向。
- 当滑块为,向上箭头、向下箭头、PageUp、PageDown、Shift + 向上箭头 和 Shift + 向下箭头 会反向。
自定义 API
通过将原始部件抽象到您自己的组件中来创建您自己的 API。
抽象所有部分
此示例抽象了 Slider
的所有部分,因此它可以作为一个自闭合元素使用。
用法
<script setup lang="ts">
import { Slider } from './your-slider'
</script>
<template>
<Slider :default-value="[25]" />
</template>
实现
// your-slider.ts
export { default as Slider } from 'Slider.vue'
<!-- Slider.vue -->
<script setup lang="ts">
import type { SliderRootEmits, SliderRootProps } from 'reka-ui'
import { SliderRange, SliderRoot, SliderThumb, SliderTrack, useForwardPropsEmits } from 'reka-ui'
const props = defineProps<SliderRootProps>()
const emits = defineEmits<SliderRootEmits>()
const forward = useForwardPropsEmits(props, emits)
</script>
<template>
<SliderRoot v-slot="{ modelValue }" v-bind="forward">
<SliderTrack>
<SliderRange />
</SliderTrack>
<SliderThumb
v-for="(_, i) in modelValue"
:key="i"
/>
</SliderRoot>
</template>
注意事项
鼠标事件未触发
由于我们在实现过程中遇到的一个限制,以下示例将无法按预期工作,并且 @mousedown
和 @mousedown
事件处理函数将不会被触发
<SliderRoot
@mousedown="() => { console.log('onMouseDown') }"
@mouseup="() => { console.log('onMouseUp') }"
>
…
</SliderRoot>
我们建议改用指针事件(例如 @pointerdown
, @pointerup
)。无论上述限制如何,这些事件更适合跨平台/设备处理,因为它们针对所有指针输入类型(鼠标、触摸、笔等)都会触发。