Reka UI 标志Reka
backdrop
组件

滑块

用户可以在给定范围内选择值的输入组件。

特性

  • 可受控或非受控。
  • 支持多个滑块手柄。
  • 支持滑块手柄之间的最小间隔值。
  • 支持通过触摸或点击轨道来更新值。
  • 支持从右到左方向。
  • 完整的键盘导航功能。

安装

从命令行安装此组件。

sh
$ npm add reka-ui

结构

导入所有部分并将其组合。

vue
<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 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

defaultValue
[0]
number[]

滑块初始渲染时的值。当您不需要控制滑块状态时使用。

dir
'ltr' | 'rtl'

适用时,组合框的阅读方向。
如果省略,则全局继承自 ConfigProvider 或假定为 LTR(从左到右)阅读模式。

disabled
false
布尔值

当为 true 时,阻止用户与滑块交互。

inverted
false
布尔值

滑块是否在视觉上反向显示。

max
100
数字

范围的最大值。

min
0
数字

范围的最小值。

minStepsBetweenThumbs
0
数字

多个滑块手柄之间允许的最小步长。

modelValue
number[] | null

滑块的受控值。可绑定为 v-model

name
string

字段的名称。随其所属的表单一起作为名称/值对提交。

orientation
'horizontal'
'vertical' | 'horizontal'

滑块的方向。

required
布尔值

当为 true 时,表示用户必须在所属表单提交前设置值。

step
1
数字

步长间隔。

thumbAlignment
'contain'
'contain' | 'overflow'

滑块手柄的对齐方式。

  • contain:滑块手柄将被限制在轨道范围内。
  • overflow:滑块手柄将不受轨道限制。不会添加额外偏移。
事件触发载荷
update:modelValue
[payload: number[]]

滑块值改变时调用的事件处理函数

valueCommit
[payload: number[]]

交互结束时值改变时调用的事件处理函数。

当您只需捕获最终值(例如更新后端服务)时很有用。

插槽(默认)载荷
modelValue
number[] | null

当前滑块值

数据属性
[data-disabled]禁用时存在
[data-orientation]"垂直" | "水平"

轨道

包含 SliderRange 的轨道。

属性默认类型
as
'span'
作为标签 | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

数据属性
[data-disabled]禁用时存在
[data-orientation]"垂直" | "水平"

范围

范围部分。必须位于 SliderTrack 内部。

属性默认类型
as
'span'
作为标签 | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

数据属性
[data-disabled]禁用时存在
[data-orientation]"垂直" | "水平"

滑块手柄

一个可拖动的滑块手柄。您可以渲染多个手柄。

属性默认类型
as
'span'
作为标签 | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

数据属性
[data-disabled]禁用时存在
[data-orientation]"垂直" | "水平"

示例

垂直方向

使用 orientation 属性来创建垂直滑块。

vue
// 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>
css
/* 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;
}

创建范围

添加多个滑块手柄和值以创建范围滑块。

vue
// 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 属性来增加步长间隔。

vue
// 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 以避免滑块手柄的值相等。

vue
// 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 (回到末尾)
将值设置为最大值。

反向滑块

当滑块为时,某些控件也会反向,具体取决于.

  • 当滑块为(默认),向右箭头向左箭头HomeEnd 会反向。
  • 当滑块为向上箭头向下箭头PageUpPageDownShift + 向上箭头Shift + 向下箭头 会反向。

自定义 API

通过将原始部件抽象到您自己的组件中来创建您自己的 API。

抽象所有部分

此示例抽象了 Slider 的所有部分,因此它可以作为一个自闭合元素使用。

用法

vue
<script setup lang="ts">
import { Slider } from './your-slider'
</script>

<template>
  <Slider :default-value="[25]" />
</template>

实现

ts
// your-slider.ts
export { default as Slider } from 'Slider.vue'
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 事件处理函数将不会被触发

vue
<SliderRoot
  @mousedown="() => { console.log('onMouseDown')  }"
  @mouseup="() => { console.log('onMouseUp')  }"
>

</SliderRoot>

我们建议改用指针事件(例如 @pointerdown, @pointerup)。无论上述限制如何,这些事件更适合跨平台/设备处理,因为它们针对所有指针输入类型(鼠标、触摸、笔等)都会触发。