n-slider 滑动选择器
在一个区间内拖动选择数值的控件:单滑块取单值、区间模式双滑块取 [start, end],支持步进、横向 / 竖向、反向、防交叉、禁用 / 只读与数值回显。点按轨道任意位置即取该处值,拖动全程连续取值(就近步进取整)。完全受控(与 n-switch / n-rate 同契约):拖动只派发目标值,回写值才驱动视觉。
- 值绑定走手动双向(组件支持 v-model,也可显式监听更新事件)。单值与区间是两条独立通道、各自类型完整:
modelValue(number)+@update:model-value,rangeValue(number[],恒有序)+@update:range-value——uts 严格类型下无需在回调里对number | number[]收窄。区间模式(range)用rangeValue通道,单值模式用modelValue通道- 步进取整在步长精度上四舍五入(0.1 类小数步长无浮点尾差),随后夹回 [min, max];建议 step 能被 (max - min) 整除(如 0 ~ 100 配 1 / 5 / 10,0 ~ 1 配 0.01),不整除时落在端点内侧最近的步进格点。
step <= 0视为连续取值(回显保留 2 位小数)- 竖向模式缺省高度走
--n-slider-vertical-height令牌(150px),custom-style="height:220px"行内覆盖。竖向拖动轴与页面滚动轴重合,滑轨区域会拦截纵向滚动(含禁用态);横向模式无此代价——轴向锁定,纵向滑动把滚动还给页面- 滑块插槽(
#startThumb/#endThumb)提供后滑块褪去内置视觉(白底 + 已选色描边 + 投影),退化为透明定位盒,内容自绘;插槽存在性在组件创建时判定(非响应式),运行期增删插槽需:key重建节点。单值模式的滑块即#startThumb
平台兼容性
| App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |
|---|---|---|---|---|---|---|
| √ | √ | √ | × | × | × | × |
API
属性
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|---|---|---|---|---|
| model-value | 当前值(单值模式);配合 @update:model-value 双向绑定,超出 [min, max] 的部分按边界夹取显示与运算 | Number | 0 | - |
| range-value | 区间值 [start, end](区间模式,传入后内部恒按有序处理);配合 @update:range-value 双向绑定,越界与缺项按 [min, max] 边界兜底显示 | Array | [0, 100] | - |
| min | 最小值(轨道起点一侧的值;须小于 max,否则跨度归零、值恒为 min) | Number | 0 | - |
| max | 最大值(轨道终点一侧的值) | Number | 100 | - |
| step | 步长(>0 时取值就近对齐步进网格;≤0 视为连续取值不 snap) | Number | 1 | - |
| range | 区间模式:渲染双滑块,值走 rangeValue 通道 | Boolean | false | - |
| reverse | 反向:值增大方向翻转(默认横向从左向右、竖向从下向上;开启后横向从右向左、竖向从上向下) | Boolean | false | - |
| vertical | 竖向:轨道纵向排布(缺省高度走 --n-slider-vertical-height 令牌,custom-style 可覆盖);拖动轴与页面滚动轴重合,滑轨区域会拦截纵向滚动 | Boolean | false | - |
| no-cross | 区间防交叉:两个滑块互为边界不可越过(关闭时可交叉穿行,两值恒有序发出) | Boolean | false | - |
| show-value | 显示当前值:单值显示在滑轨右(竖向为下方),区间两值分列滑轨两侧(竖向为下方一行) | Boolean | false | - |
| readonly | 只读:纯展示,拦截拖动与点按,无视觉降级(结果回显场景) | Boolean | false | - |
| disabled | 禁用:保色相整体降透明(--n-slider-disabled-opacity),拦截拖动与点按 | Boolean | false | - |
| thumb-size | 滑块直径 px(圆形,小于 1 按 1 处理;触摸行高度随之推导,触控下限 40px) | Number | 20 | - |
| rail-height | 轨道厚度 px(横向为高度、竖向为宽度,小于 1 按 1 处理;圆角自动为胶囊形) | Number | 4 | - |
| rail-color | 轨道底色(实色值);留空取主题令牌 --n-slider-rail-color(缺省挂全局表面色 --n-bg-2,深浅主题自动) | String | "" | 与 css 相同 |
| active-color | 已选段颜色(实色值,同时作为滑块描边色);留空取主题品牌色 | String | "" | 与 css 相同 |
| thumb-color | 滑块底色(实色值);留空为白色(--n-slider-thumb-color) | String | "" | 与 css 相同 |
| value-style | 数值文字行内样式(字号 / 颜色 / 宽度等直达;数值盒默认定宽 --n-slider-value-width,过长数值经此调宽) | String | "" | 与 css 相同 |
| custom-class | 挂到根节点的额外 class(类需定义在组件样式表内) | String | "" | - |
| custom-style | 根节点行内样式,如 "margin-top:14px"(竖向模式给 height 控制轨道长度) | String | "" | 与 css 相同 |
事件
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| update:modelValue | 单值模式下拖动或点按轨道使值变化时触发(点按落点即取值、拖动全程持续发出),参数为最新值;配合 :model-value 手动双向绑定 | 最新值 number |
| update:rangeValue | 区间模式下值变化时触发,参数为 [start, end](恒有序);配合 :range-value 手动双向绑定 | 最新区间 number[] |
| change | 值稳定时触发(松手或点按轨道落定后),单值模式参数为 number、区间模式为 number[];与拖动过程中不重复 | 稳定值 number / number[] |
| changing | 拖动过程中值变化时持续触发(点按落点取值同发),参数同 change;实时联动场景监听此事件 | 当前值 number / number[] |
| dragStart | 手势开始(按下)时触发,参数为手势开始时刻的当前值(未跳到落点值) | 按下时值 number / number[] |
| dragEnd | 手势结束(松手或被来电等打断)时触发,参数为结束时刻的当前值;值有变化时与 change 同时发出 | 结束值 number / number[] |
插槽
| 插槽名 | 说明 |
|---|---|
| startThumb | 起始滑块内容(单值模式即唯一滑块);提供后滑块褪去内置视觉,内容自绘(定位盒尺寸 = thumb-size,内容居中) |
| endThumb | 结束滑块内容(区间模式第二个滑块);同 startThumb 的定制方式 |
实现说明
-
越界夹取与区间排序由组件内部派生,调用者直接绑定原始数值即可。竖向默认宽度由组件内部触控尺寸推导,customStyle 仍可覆盖;示例不再重复计算触控宽度或修正输入值。
-
取值换算:手势开始时实测轨道视口矩形(每次手势重测,旋转屏幕 / 容器改宽等布局漂移在下一次手势自愈),触摸坐标 → 轨道内比例 → 步进网格就近取整 → 越界格点落端点内侧最近格点(值恒在步进网格上);测量回调里同步完成点按落点取值与区间就近选块(等距归起始滑块)。显示链路(滑块 / 已选段定位)走百分比 + 固定 px 偏移,全程免测量
-
手势收尾时序:横向模式按下时刻无法预知用户意图(点按取值还是纵向滚动页面),取值权在位移判定为横向(≥8px 首位移判横竖)或松手收口时才授予——纵向让位的手势全程不落值、页面零误触;点按落点取值发生在 touchend 收口(末触点)。轨道测量是异步的,快速点按时 touchend 可能先于测量回调到达——收尾挂起等回调落值后再统一收口,点按落点取值不丢,事件序列恒为 dragStart → changing… → dragEnd → change(值有变化时)。手势被打断(touchcancel)时已派发的值不回滚、不补落末触点值。单手势模型:手势进行中再按下(多指)不重置判定、不重复 dragStart
-
Web 端坐标系差:选择器查询的 top 相对页面内容区(导航栏之下,同 CSS 变量 --window-top),触摸 clientY 相对浏览器视口,两者相差 windowTop——测量时按
uni.getWindowInfo().windowTop补齐(条件编译仅 Web 生效;App / 小程序两侧同为页面视口语义无差)。响应式顶栏(top-window)布局下的残余差异不补偿(无对应查询字段,属罕用布局) -
双滑块交叉:持续写入手势起始槽位、发出前排序——被拖值恒为行进方向的极端值,两滑块互相穿行时视觉连续不跳变(值恒有序);noCross 开启时另一槽位值作夹板,滑块互为边界。写值事实源是手势起始的槽位值快照(含本手势写值),不读回写值——props 回写一拍滞后且排序后槽位与值错位,读它组合落值会把本手势先前落的值污染进未拖槽位(被拖滑块推移另一滑块、收口补落撞值);未拖滑块恒保持手势起始值
-
竖向滚动取舍:竖向拖动轴与页面滚动轴重合,无法靠轴向锁定让位,滑轨 touchmove 拦截滚动(横向模式轴向锁定:首次位移 ≥8px 判横竖,纵向让位页面滚动)
-
按压放大与容器裁剪:滑块中心行程贴组件盒界(轨道两端各留 thumb-size/2 边距),按压放大反馈(scale 1.2)两端各跨出盒界 (1.2−1)/2 × thumb-size;组件自身裁剪链(根 / 触摸行 / 轨道)已整体放行 overflow,但 uvue 端 view 默认 hidden——嵌入紧贴边界的裁剪容器(卡片、固定底栏等)时,需将对应容器放行,否则跨出部分被裁
-
参考并集裁剪记录:触摸行主尺寸 prop 不收(由滑块直径 + 触控下限 40px 自动推导);滑块描边 / 圆角、轨道圆角、数值盒宽高微样式 props 不收(走令牌 + value-style / custom-style 行内通道,n-switch 同款纪律);数值作用域插槽不收(受控值本就在使用者手里,自定义回显旁置 n-text 等价,n-rate 同款先例);单通道多态值不收(uts 严格类型下双通道各自类型完整);定宽滑轨不收(铺满父容器 + custom-style 覆盖)