Skip to content
🌏 Translated with the assistance of DeepSeek and ChatGPT

Slider

This component somehow reminds me of a sliding rheostat, and this piece of music. 😂

Basic Usage

Pass modelValue to enter controlled mode. If not passed or is undefined, it will be in uncontrolled mode, where you can pass the defaultValue prop as the default value.

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 Selection

The range prop enables range selection.

<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>

Value Range, Step & Precision

min and max set the numerical range. step sets the step size; when it is 0, the step size is not limited.

The precision parameter controls the minimum precision of the numerical value. It takes an integer in [0, 100]; when it is null, the minimum precision is not limited.

Setting the precision parameter is primarily intended to handle unexpected approximate values resulting from precision loss in JS floating-point calculations.

<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

readonly sets it to read-only, disabled sets it to disabled. The only difference between them is almost just the styling.

<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

marks sets the marks on the slider. When step is set to 'mark', only values at the marks can be selected.

<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>

Label Rendering

The mark slot customizes the rendering of labels of marks.

<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>

Vertical Orientation

direction sets the orientation of the slider. When vertical, the height defaults to the container's height, but you can also set the height yourself.

<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>

Track Reversal

direction sets the orientation of the slider. When vertical, the height defaults to the container's height, but you can also set the height yourself.

<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 Indicator

You can use the thumb, thumb-start, and thumb-end slots to customize the content inside the thumbs.

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

AttributeTypeOptionalDefaultDescriptionVersion
modelValuenumber | [number, number] | nullTrueThe value of the slider (controlled mode), supports v-model.0.0.3
defaultValuenumber | [number, number] | nullTrueThe default value of the slider (uncontrolled mode).0.0.3
minnumberTrue0The minimum value of the slider (inclusive).0.0.3
maxnumberTrue100The maximum value of the slider (inclusive).0.0.3
rangebooleanTruefalseRange selection.0.0.3
disabledbooleanTruefalseDisabled state.0.0.3
readonlybooleanTruefalseRead-only state.0.0.3
stepnumber | 'mark'True1The step size of the values.0.0.3
marks(number | { value: number; label?: string })[]TrueMarks on the slider.0.0.3
direction'horizontal' | 'vertical'True'horizontal'The orientation of the slider.0.0.3
reversebooleanTruefalseWhether to reverse the track.0.0.3
precisionnumber | nullTrue80.0.3
tooltipbooleanTruetrueWhether to enable text tooltip.0.0.3
tooltipPropsOmit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents>TrueProps for the Tooltip component in single-value mode.0.0.3
tooltipStartPropsOmit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents>TrueProps for the first Tooltip component in range selection mode.0.0.3
tooltipEndPropsOmit<TooltipProps, 'visible' | 'content'> & EmitEvent<TooltipEvents>TrueProps for the second Tooltip component in range selection mode.0.0.3

SliderEvent

AttributeTypeOptionalDefaultDescriptionVersion
'update:modelValue'False0.0.3
changeFalse0.0.3
dragStartFalse0.0.3
dragEndFalse0.0.3
markSelectFalse0.0.3
focusFalse0.0.3
blurFalse0.0.3

SliderSlots

SlotParameterDescriptionVersion
markvalue: number, label: string | undefinedRendering of mark labels.0.0.3
thumbContent of the thumb in single-value mode.0.0.3
thumb-startContent of the first thumb in range selection mode.0.0.3
thumb-endContent of the second thumb in range selection mode.0.0.3
tooltip-contentvalue: numberContent of the text tooltip.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
}