更新记录

0.0.1(2026-09-11) 下载此版本

init


平台兼容性

uni-app(3.99)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - -

l-slider 双滑块范围选择器

uni-app 自定义双滑块组件,适用于"数值区间选择"场景(如阈值上下限、筛选范围)。 纯触摸事件实现,无第三方组件库依赖,可复制到任意 uni-app + Vue3 + TS 项目使用。

功能特性

  • 双滑块独立拖动,允许两滑块交叉(对外输出自动按 min/max 排序)
  • 拖动过程中实时更新 v-model 并触发 changing 事件
  • 松手时触发 change 事件(适合提交/查询场景)
  • step 步长自动对齐(取最近步长倍数)
  • 每个滑块下方实时跟随显示当前数值
  • 默认主题紫色 #7c3aed,三处色值可一键替换

接入方式

l-slider.vue 复制到项目 src/components/l-slider/ 目录。

方式一:easycom 自动注册(推荐)

符合项目 easycom 规则(components/l-slider/l-slider.vue)时,模板直接使用,无需 import。

方式二:手动注册

<script setup>
import lSlider from "@/components/l-slider/l-slider.vue";
</script>

基本用法

方式一:v-model + computed 直写表单(推荐)

适合"最终要提交整个配置对象"的场景,拖动时直接写回表单数据:

<template>
  <view>
    <!-- 显示文字随拖动实时更新 -->
    <view>{{ config.hr.min }} - {{ config.hr.max }}</view>
    <l-slider v-model="hrSlider" :min="1" :max="150" :step="1" />
  </view>
</template>

<script setup lang="ts">
const config = ref({
  hr: { min: 40, max: 130 },
});

// get 从表单读,set 写回表单;提交时直接用 config,无需中转变量
const hrSlider = computed<[number, number]>({
  get: () => [config.value.hr.min, config.value.hr.max] as [number, number],
  set: (val: [number, number]) => {
    const a = val[0];
    const b = val[1];
    config.value.hr.min = Math.min(a, b); // 自动排序,保证 min <= max
    config.value.hr.max = Math.max(a, b);
  },
});
</script>

方式二:独立 ref + change 事件

适合临时记录范围的场景:

<template>
  <l-slider
    v-model="range"
    :min="0"
    :max="100"
    :step="5"
    @change="handleChange"
  />
</template>

<script setup lang="ts">
const range = ref<[number, number]>([20, 70]);

// 松手时触发,min/max 为排序后的值
const handleChange = (min: number, max: number) => {
  console.log("最终范围:", min, max);
};
</script>

API

Props

参数 说明 类型 默认值
v-model 双滑块当前值 [a, b],拖动中实时更新 [number, number] [20, 70]
min 可选范围最小值 number 0
max 可选范围最大值 number 100
step 步长,拖动值自动对齐步长倍数 number 1

Events

事件名 说明 回调参数
update:modelValue 拖动中和松手时均触发,回传 [a, b](未排序,按滑块顺序) (val: [number, number])
changing 拖动过程中持续触发 (min: number, max: number) 排序后
change 松手时触发,适合提交/查询场景 (min: number, max: number) 排序后

需要实时显示时直接从 v-model 派生即可,无需监听 changing

交互行为说明

  • 拖动热区touchmove 绑定在轨道上,手指移出滑块范围仍可持续拖动,不中断
  • 位置算法:触点绝对位置计算(clientX - 轨道left),快速滑动不丢帧
  • 滑块交叉:A/B 滑块可互相越过,change/changing 输出始终是排序后的 [min, max]
  • 边界收敛:拖动值自动收敛到 [min, max] 区间

样式定制

默认主题紫色 #7c3aed,出现三处(l-slider.vue#L183L190L211):

class 作用 当前样式
.range-track 轨道 高 8rpx,灰色 #e5e5e5
.range-active 选中区间高亮条 #7c3aed
.range-block 滑块圆点(40rpx) #7c3aed
.block-value 滑块下方数值 #7c3aed,24rpx 粗体

统一换色:全局替换 #7c3aed 即可。接入 uview-pro 项目可改为 var(--u-type-primary) 跟随主题。

覆盖尺寸示例(父组件样式,注意 scoped 下需 :deep()):

:deep(.range-track) {
  height: 12rpx;
}

注意事项

  1. v-model 传入数组长度超过 2 时,多余项被忽略
  2. 只处理单指触摸(touches[0]),不支持双指
  3. 依赖触摸事件,桌面浏览器鼠标拖动无效,请在真机/移动端模拟器调试
  4. 建议让 (max - min)step 的整数倍,否则 max 可能无法被精确选中
  5. 轨道位置在 onMounted 时测量一次;组件初始化时若处于隐藏状态(如父容器 display:none),需在显示后重新测量(可暴露 getTrackRect 方法或用 v-if 重建组件)

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。