效果展示

微信小程序--自定义slider组件_自定义

Demo代码

index.wxml

<text>slider组件自定义</text> {{value}}
<view class="component-slider">
<!-- 覆盖slider组件盒子 -->
<view class="slider-box">
<!-- 拖动按钮 -->
<view class="slider-btn" style="margin-left: {{ (value-min)*(102/(max-min))-7 }}%;" ></view>
<!-- 未选中区线 -->
<view class="slider-line"></view>
<!-- 选中区线 -->
<view class="slider-line-active" style="width: {{ (value-min)*(102/(max-min))-7 }}%;"></view>
<!-- 显示数字 -->
<view class="slider-number">
<!-- 最小限制大于等于0 -->
<block wx:if="{{min>=0}}" >
<block wx:for="{{max+1}}" wx:key="index" >
<text class="{{value==item?'active':''}}" style="left:{{ (item-min)*(100/(max-min))-2 }}%" >{{item}}</text>
</block>
</block>
<!-- 最小限制小于0 -->
<block wx:else>
<block wx:for="{{(max-min)+1}}" wx:key="index">
<text class="{{value==(item+min)?'active':''}}" style="left:{{ (item)*(102/(max-min))-2 }}%" >{{item+min}}</text>
</block>
</block>
</view>
</view>
<!-- slider组件 -->
<slider block-size="28" bindchange="sliderchange" bindchanging="sliderchanging" min="{{min}}" max="{{max}}" value="{{value}}" />
</view>

index.wxss

.component-slider {
width: 90%;
position: relative;
margin: 0rpx auto 0rpx;
padding: 70rpx 0 70rpx;
}

/* 盒子 */
.slider-box {
width: 88%;
margin: 0 auto;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}

/* 未选中区线 */
.slider-line {
width: 100%;
height: 10rpx;
background: rgba(91, 150, 246, 0.1);
margin: 0 auto;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}

/* 选中区线 */
.slider-line-active {
position: absolute;
left: 0;
top: 50%;
transform: translate(0, -50%);
height: 10rpx;
background: #5B96F6;
}

/* slider按钮 */
.slider-btn {
width: 70rpx;
height: 35rpx;
background: #5B96F6;
border-radius: 20rpx;
}

/* 显示的数字 */
.slider-number {
width: 100%;
position: absolute;
bottom: -10rpx;
}

.slider-number text {
position: absolute;
top: 0;
font-size: 24rpx;
color: #999999;
transition: all 0.3s;
}

/* 当前选中的数字 */
.slider-number text.active {
font-size: 32rpx;
color: #5B96F6;
transition: all 0.3s;
}

/* slider组件设置透明 */
slider {
opacity: 0;
}

index.json

{
"usingComponents": {}
}

index.js

Page({
data: {
min: 0, // 最小限制
max:5, // 最大限制
value:0, // 当前value
},
// 拖动过程中触发的事件
sliderchanging(e){
var value = e.detail.value;
this.setData({ value: value })
},
// 完成一次拖动后触发的事件
sliderchange(e){
var value = e.detail.value;
this.setData({ value: value })
}
})

思路

本质上其实还是利用的是原生的slider,只是将其透明度设置为0,用户看不到,然后再在其上面添加一个自定义按钮,同时进度条也是需要重新绘制

微信小程序--自定义slider组件_微信小程序_02

微信小程序--自定义slider组件_ide_03


在代码中可以看到:

<!-- 拖动按钮 -->
<view class="slider-btn" style="margin-left: {{ (value-min)*(102/(max-min))-7 }}%;"></view>

其中margin-left: {{ (value-min)*(102/(max-min))-7 }}%;就是动态设置按钮的位置

按照常理来说,应该是 (value-min)*(100/(max-min))}}% 【解释:只需要算出当前值占总长的几分之几就可以了,其实是(value-min)/(max-min) ✖️100】

举个例子:总范围是0-10,此时的数值是7,那么已经滑动距离占总长的:(7-0)/10=0.7,这里需要百分数,所以乘了100

当css样式为margin-left:(value-min)*(100/(max-min))}}%时

微信小程序--自定义slider组件_xml_04


可以发现,自定义滑块并没有与原生slider重合,所以需要稍微调整一下

得到:margin-left: {{ (value-min)*(102/(max-min))-7 }}%

而进度条中的style就可以设置为:"width: {{ (value-min)*(100/(max-min)) }}%;

具体看自定义滑块、线条的定义,再进行一定的微调即可

举一反三

微信小程序--自定义slider组件_微信小程序_05

修改slider按钮css样式就可以了

/* slider按钮 */
.slider-btn {
width: 70rpx;
height: 70rpx;
background: #5B96F6;
border-radius: 100%;
}

当然,线条、按钮的格式也可以自定义为其他样式

微信小程序--自定义slider组件_slider_06


修改部分:

wxml

<view class="slider-btn" style="background: #ed5a65;margin-left: {{ (speed_left-min)*(102/(max-min))-7 }}%;">L
</view>

wxss

.slider-btn {
width: 80rpx;
height: 45rpx;
font-size: 18px;
color: white;
text-align: center;
padding: -1px;
border-radius: 20rpx;
}