跳至内容

滑块

用户从给定范围内选择值的输入。
vue
<script setup lang="ts">
import { ref } from 'vue'
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'radix-vue'

const sliderValue = ref([50])
</script>

<template>
  <SliderRoot
    v-model="sliderValue"
    class="relative flex items-center select-none touch-none w-[200px] h-5"
    :max="100"
    :step="1"
  >
    <SliderTrack class="bg-blackA10 relative grow rounded-full h-[3px]">
      <SliderRange class="absolute bg-white rounded-full h-full" />
    </SliderTrack>
    <SliderThumb
      class="block w-5 h-5 bg-white shadow-[0_2px_10px] shadow-blackA7 rounded-[10px] hover:bg-violet3 focus:outline-none focus:shadow-[0_0_0_5px] focus:shadow-blackA8"
      aria-label="Volume"
    />
  </SliderRoot>
</template>

功能

  • 可以是受控或不受控的。
  • 支持多个滑块。
  • 支持滑块之间的最小值。
  • 支持触摸或点击轨道以更新值。
  • 支持从右到左的方向。
  • 完整的键盘导航。

安装

从命令行安装组件。

sh
$ npm add radix-vue

解剖学

导入所有部分并将其拼凑在一起。

vue
<script setup>
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'radix-vue'
</script>

<template>
  <SliderRoot>
    <SliderTrack>
      <SliderRange />
    </SliderTrack>
    <SliderThumb />
  </SliderRoot>
</template>

API 参考

包含滑块的所有部分。当在form中使用时,它将为每个滑块渲染一个input,以确保事件正确传播。

道具默认类型
as
'div'
AsTag | 组件

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

asChild
布尔值

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

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

defaultValue
[0]
number[]

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

dir
'ltr' | 'rtl'

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

disabled
false
布尔值

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

inverted
false
布尔值

滑块是否被视觉反转。

max
100
数字

范围的最大值。

min
0
数字

范围的最小值。

minStepsBetweenThumbs
0
数字

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

modelValue
number[]

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

name
字符串
orientation
'horizontal'
'vertical' | 'horizontal'

滑块的方向。

step
1
数字

步进间隔。

发出有效载荷
update:modelValue
[有效载荷:number[]]

当滑块值更改时调用的事件处理程序

valueCommit
[有效载荷:number[]]

交互结束时值更改时调用的事件处理程序。

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

插槽(默认)有效载荷
modelValue
number[]

当前滑块值

数据属性价值
[data-disabled]禁用时出现
[data-orientation]"vertical" | "horizontal"

轨道

包含SliderRange的轨道。

道具默认类型
as
'span'
AsTag | 组件

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

asChild
布尔值

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

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

数据属性价值
[data-disabled]禁用时出现
[data-orientation]"vertical" | "horizontal"

范围

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

道具默认类型
as
'span'
AsTag | 组件

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

asChild
布尔值

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

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

数据属性价值
[data-disabled]禁用时出现
[data-orientation]"vertical" | "horizontal"

滑块

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

道具默认类型
as
'div'
AsTag | 组件

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

asChild
布尔值

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

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

数据属性价值
[data-disabled]禁用时出现
[data-orientation]"vertical" | "horizontal"

示例

垂直方向

使用orientation道具创建垂直滑块。

vue
// index.vue
<script setup>
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'radix-vue'
</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 'radix-vue'
</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 'radix-vue'
</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 'radix-vue'
</script>

<template>
  <SliderRoot
    :default-value="[25, 75]"
    :step="10"
    :min-steps-between-thumbs="1"
  >
    <SliderTrack>
      <SliderRange />
    </SliderTrack>
    <SliderThumb />
    <SliderThumb />
  </SliderRoot>
</template>

无障碍

遵循滑块 WAI-ARIA 设计模式

键盘交互

钥匙描述
ArrowRight
根据orientationstep值为增量/减量。
ArrowLeft
根据orientationstep值为增量/减量。
ArrowUp
将值增加step量。
ArrowDown
将值减少step量。
PageUp
将值增加更大的step
PageDown
将值减少更大的step
Shift + ArrowUp
将值增加更大的step
Shift + ArrowDown
将值减少更大的step
Home
将值设置为最小值。
End
将值设置为最大值。

自定义 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 { SlideRoot, SliderRange, type SliderRootEmits, type SliderRootProps, SliderThumb, SliderTrack, useForwardPropsEmits } from 'radix-vue'

const props = defineProps<SliderRootProps>()
const emits = defineEmits<SliderRootEmits>()

const forward = useForwardPropsEmits(props, emits)
</script>

<template>
  <SliderRoot v-bind="forward">
    <SliderTrack>
      <SliderRange />
    </SliderTrack>

    <SliderThumb
      v-for="(_, i) in value"
      :key="i"
    />
  </SliderRoot>
</template>

注意事项

鼠标事件未触发

由于实施期间遇到的限制,以下示例将无法按预期工作,并且@mousedown@mousedown事件处理程序将不会触发

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

</SliderRoot>

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