滑动选择器 Slider
这个组件让我莫名其妙地想到了滑动变阻器,和这段音乐。😂
基础使用
传入 modelValue 进入受控模式。不传或者为 undefined 则为非受控模式,此时可以传入 defaultValue 属性作为默认值。
Controlled
Uncontrolled
<template>
<px-space direction="vertical">
<h4>Controlled</h4>
<px-slider v-model="input"></px-slider>
<px-input-number v-model="input" :min="0" :max="100"></px-input-number>
<h4>Uncontrolled</h4>
<px-slider :default-value="50"></px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const input = ref(0)
</script>
<style lang="css" scoped>
.px-slider,
.px-input-number {
width: 400px;
}
</style>范围选择
range 属性可开启范围选择。
<template>
<px-space direction="vertical">
<px-slider v-model="input"></px-slider>
<px-slider :default-value="[25, 50]" range></px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const input = ref([0, 10])
</script>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>数值范围、步长、精度
min 和 max 设置数值范围。step 设置步长,为 0 时不限制步长。
precision 参数控制数值最小精度,取值为 [0, 100] 的整数,为 null 时不限制最小精度。
设置
precision参数主要是为了处理 JS 浮点数计算中因精度丢失产生的非预期近似值。
<template>
<px-space direction="vertical">
<px-slider v-model="input0" :min="0" :max="114514" :step="114"></px-slider>
<px-input-number v-model="input0" :min="0" :max="114514" :step="114"></px-input-number>
<px-slider v-model="input1" :min="0" :max="114514" :step="0"></px-slider>
<px-input-number v-model="input1"></px-input-number>
<px-slider v-model="input2" :min="0" :max="114514" :step="0" :precision="null"></px-slider>
<px-input-number v-model="input2"></px-input-number>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const input0 = ref(0)
const input1 = ref(0)
const input2 = ref(0)
</script>
<style lang="css" scoped>
.px-slider,
.px-input-number {
width: 400px;
}
</style>只读 & 禁用
readonly 设置只读,disabled 设置禁用。它们之间几乎只有样式不一样。
<template>
<px-space direction="vertical">
<px-slider :default-value="75" readonly></px-slider>
<px-slider :default-value="25" disabled></px-slider>
</px-space>
</template>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>标记点
marks 设置标记点,设置 step 为 'mark' 时仅支持选择标记点的数值。
<template>
<px-space direction="vertical">
<px-slider v-model="input0" :marks="marks" :step="0.01"></px-slider>
<px-slider v-model="input1" :marks="marks" step="mark"></px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const input0 = ref(50)
const input1 = ref(50)
const marks = [{ value: 15.87, label: 'μ-σ' }, 50, { value: 84.13, label: 'μ+σ' }]
</script>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>标签渲染
mark 插槽自定义标记点的标签渲染。
<template>
<px-space direction="vertical">
<px-slider v-model="input0" :marks="marks" :step="0.01">
<template #mark="{ value, label }">
<div
style="display: flex; align-items: center"
:style="{ color: value < 50 ? '#FF7D00' : '#00B42A' }"
>
<IconAnalytics style="margin-right: 4px"></IconAnalytics>
{{ label || 'μ' }}
</div>
</template>
</px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { IconAnalytics } from '@pixelium/web-vue/icon-hn/es'
const input0 = ref(50)
const marks = [{ value: 15.87, label: 'μ-σ' }, 50, { value: 84.13, label: 'μ+σ' }]
</script>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>垂直方向
direction 设置滑动选择器方向,垂直时高度默认为容器高度,你也可以自己设置高度。
<template>
<px-space>
<px-slider v-model="input" direction="vertical"></px-slider>
<px-slider v-model="input" direction="vertical" :marks="marks"></px-slider>
<px-slider v-model="input" range direction="vertical"></px-slider>
<px-slider v-model="input" range direction="vertical" :marks="marks">
<template #mark="{ value, label }">
<div
style="display: flex; align-items: center"
:style="{ color: value < 30 ? '#FF7D00' : '#00B42A' }"
>
<IconBolt style="margin-right: 4px"></IconBolt>
{{ label || 'μ' }}
</div>
</template>
</px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { IconBolt } from '@pixelium/web-vue/icon-hn/es'
const input = ref(0)
const marks = [
{ value: 0, label: '0%' },
{ value: 25, label: '25%' },
{ value: 50, label: '50%' },
{ value: 75, label: '75%' },
{ value: 100, label: '100%' }
]
</script>
<style lang="css" scoped>
.px-slider {
height: 400px;
margin-right: 48px;
}
</style>轨道反转
direction 设置滑动选择器方向,垂直时高度默认为容器高度,你也可以自己设置高度。
<template>
<px-space>
<px-space direction="vertical">
<px-slider v-model="input" :marks="marks"></px-slider>
<px-slider v-model="inputRange" range :marks="marks"></px-slider>
<px-slider v-model="input" reverse :marks="marks"></px-slider>
<px-slider v-model="inputRange" reverse range :marks="marks"></px-slider>
</px-space>
<px-space>
<px-slider v-model="input" direction="vertical" :marks="marks"></px-slider>
<px-slider v-model="inputRange" range direction="vertical" :marks="marks"></px-slider>
<px-slider v-model="input" reverse direction="vertical" :marks="marks"></px-slider>
<px-slider
v-model="inputRange"
reverse
range
direction="vertical"
:marks="marks"
></px-slider>
</px-space>
</px-space>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const marks = [
{ value: 0, label: '0°C' },
{ value: 20, label: '20°C' },
{ value: 37, label: '37°C' },
{ value: 100, label: '100°C' },
50
]
const inputRange = ref([0, 10])
const input = ref(37)
</script>
<style lang="css" scoped>
.px-slider__horizontal {
width: 400px;
}
.px-slider__vertical {
height: 400px;
margin-right: 24px;
margin-left: 24px;
}
</style>滑块标识
可以使用 thumb、thumb-start、thumb-end 插槽自定义滑块中的内容。
L
R
<template>
<px-space direction="vertical">
<px-slider :default-value="50">
<template #thumb>
<IconHumanRun></IconHumanRun>
</template>
</px-slider>
<px-slider :default-value="[25, 50]" range>
<template #thumb-start> L </template>
<template #thumb-end> R </template>
</px-slider>
</px-space>
</template>
<script lang="ts" setup>
import { IconHumanRun } from '@pixelium/web-vue/icon-pa/es'
</script>
<style lang="css" scoped>
.px-slider {
width: 400px;
}
</style>API
SliderProps
| 属性 | 类型 | 可选 | 默认值 | 描述 | 版本 |
|---|---|---|---|---|---|
| modelValue | number | [number, number] | null | 是 | | 滑动选择器的值(受控模式),支持 v-model。 | 0.0.3 |
| defaultValue | number | [number, number] | null | 是 | | 滑动选择器的默认值(非受控模式)。 | 0.0.3 |
| min | number | 是 | 0 | 滑动选择器的最小值(闭区间)。 | 0.0.3 |
| max | number | 是 | 100 | 滑动选择器的最大值(闭区间)。 | 0.0.3 |
| range | boolean | 是 | false | 范围选择。 | 0.0.3 |
| disabled | boolean | 是 | false | 禁用状态。 | 0.0.3 |
| readonly | boolean | 是 | false | 只读状态。 | 0.0.3 |
| step | number | 'mark' | 是 | 1 | 数值的步长。 | 0.0.3 |
| marks | (number | { value: number; label?: string })[] | 是 | | 滑动选择器的标记点。 | 0.0.3 |
| direction | 'horizontal' | 'vertical' | 是 | 'horizontal' | 滑动选择器的方向。 | 0.0.3 |
| reverse | boolean | 是 | false | 是否反转轨道。 | 0.0.3 |
| precision | number | null | 是 | 8 | 数值最小精度,取值为 [0, 100] 的整数,为 null 时不限制。 | 0.0.3 |
| tooltip | boolean | 是 | true | 是否开启文本提示。 | 0.0.3 |
| tooltipProps | Omit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents> | 是 | | 单值模式时,文本提示 Tooltip 组件的属性。 | 0.0.3 |
| tooltipStartProps | Omit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents> | 是 | | 范围选择模式时,第一个文本提示 Tooltip 组件的属性。 | 0.0.3 |
| tooltipEndProps | Omit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents> | 是 | | 范围选择模式时,第二个文本提示 Tooltip 组件的属性。 | 0.0.3 |
SliderEvent
| 属性 | 类型 | 可选 | 默认值 | 描述 | 版本 |
|---|---|---|---|---|---|
| 'update:modelValue' | | 否 | | 0.0.3 | |
| change | | 否 | | 0.0.3 | |
| dragStart | | 否 | | 0.0.3 | |
| dragEnd | | 否 | | 0.0.3 | |
| markSelect | | 否 | | 0.0.3 | |
| focus | | 否 | | 0.0.3 | |
| blur | | 否 | | 0.0.3 |
SliderSlots
| 插槽 | 参数 | 描述 | 版本 |
|---|---|---|---|
| mark | value: number, label: string | undefined | 标记点标签的渲染。 | 0.0.3 |
| thumb | | 单值模式时,滑块的内容。 | 0.0.3 |
| thumb-start | | 范围选择模式时,第一个滑块的内容。 | 0.0.3 |
| thumb-end | | 范围选择模式时,第二个滑块的内容。 | 0.0.3 |
| tooltip-content | value: number | 文本提示的内容。 | 0.0.3 |
EmitEvent
ts
export type EmitEvent<T extends Record<string, any>> = {
[K in keyof T as `on${Capitalize<K & string>}`]?: (...args: T[K]) => void
}1
2
3
2
3