Skip to content

滑动选择器 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>

数值范围、步长、精度

minmax 设置数值范围。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>

滑块标识

可以使用 thumbthumb-startthumb-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

属性类型可选默认值描述版本
modelValuenumber | [number, number] | null滑动选择器的值(受控模式),支持 v-model0.0.3
defaultValuenumber | [number, number] | null滑动选择器的默认值(非受控模式)。0.0.3
minnumber0滑动选择器的最小值(闭区间)。0.0.3
maxnumber100滑动选择器的最大值(闭区间)。0.0.3
rangebooleanfalse范围选择。0.0.3
disabledbooleanfalse禁用状态。0.0.3
readonlybooleanfalse只读状态。0.0.3
stepnumber | 'mark'1数值的步长。0.0.3
marks(number | { value: number; label?: string })[]滑动选择器的标记点。0.0.3
direction'horizontal' | 'vertical''horizontal'滑动选择器的方向。0.0.3
reversebooleanfalse是否反转轨道。0.0.3
precisionnumber | null8数值最小精度,取值为 [0, 100] 的整数,为 null 时不限制。0.0.3
tooltipbooleantrue是否开启文本提示。0.0.3
tooltipPropsOmit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents>单值模式时,文本提示 Tooltip 组件的属性。0.0.3
tooltipStartPropsOmit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents>范围选择模式时,第一个文本提示 Tooltip 组件的属性。0.0.3
tooltipEndPropsOmit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents>范围选择模式时,第二个文本提示 Tooltip 组件的属性。0.0.3

SliderEvent

属性类型可选默认值描述版本
'update:modelValue'0.0.3
change0.0.3
dragStart0.0.3
dragEnd0.0.3
markSelect0.0.3
focus0.0.3
blur0.0.3

SliderSlots

插槽参数描述版本
markvalue: number, label: string | undefined标记点标签的渲染。0.0.3
thumb单值模式时,滑块的内容。0.0.3
thumb-start范围选择模式时,第一个滑块的内容。0.0.3
thumb-end范围选择模式时,第二个滑块的内容。0.0.3
tooltip-contentvalue: 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
}