真正开发过小程序的开发者会发现,小程序里面的单选框和多选框封封装的实在不够友好,一般与UI都会有比较大的出入,所以下面来探讨一下单选框和多选框的封装。
比如我们要做一个这种样式的单选框和多选框组件,我们改怎么去处理呢?
<!-- 判断某个元素是不是指定数组内 -->
<wxs module="checkbox">
var checkStatus = function (arr, item) {
return arr.indexOf(item) >= 0
};
module.exports.checkStatus = checkStatus;
</wxs>
<view hidden='{{isHidden}}'>
<!-- 单选组件 -->
<radio-group
class="radio-group"
bindchange="radioChange"
wx:if="{{selectType == 'radio'}}">
<label
class='{{radioIndex == item.index ? focusRadioClass : initRadioClass}}'
wx:for="{{radioData}}"
wx:key="{{index}}"
id="{{item.index}}">
<view class='item-index'>
<radio
style='opacity: 0'
value="{{item.index}}"
checked="{{item.checked}}"/>
<view class='index'>{{item.index}}</view>
</view>
<view class='flex-item text-center'>{{item.value}}</view>
</label>
</radio-group>
<!-- 多选组件 -->
<checkbox-group
class="checkbox-group"
bindchange="checkboxChange"
wx:if="{{selectType == 'checkbox'}}">
<label
class='{{checkbox.checkStatus(checkboxIndexArr, item.index) ? focusCheckboxClass : initCheckboxClass}}'
wx:for="{{checkboxData}}"
wx:key="{{index}}"
id="{{item.index}}">
<view class='item-index'>
<checkbox
style='opacity: 0'
value="{{item.index}}"
checked="{{item.checked}}"
disabled="{{checkboxIndexArr.length > maxLength - 1 && !checkbox.checkStatus(checkboxIndexArr, item.index)}}"/>
<view class='index'>{{item.index}}</view>
</view>
<view class='flex-item text-center'>
{{item.value}}
</view>
</label>
<view>{{checkboxIndexArr.prototype}}</view>
</checkbox-group>
</view>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
复制
.flex-wrapper {
display: flex;
}
.flex-item {
flex: 1;
}
.text-center {
text-align: center;
}
.radio-group, .checkbox-group {
margin: 0 auto;
width: 490rpx;
}
.radio-group label, .checkbox-group label {
margin-bottom: 50rpx;
height: 68rpx;
line-height: 68rpx;
border: 1rpx solid #000;
border-radius: 10rpx;
font-size: 30rpx;
color: #000;
}
.radio-group label.active, .checkbox-group label.active {
background-color: #fcc919;
}
.radio-group label .item-index, .checkbox-group label .item-index {
position: relative;
flex: 0 0 40rpx;
margin: 0 0 0 20rpx;
width: 40rpx;
height: 68rpx;
}
.radio-group label .item-index .index, .checkbox-group label .item-index .index {
position: absolute;
top: 0;
bottom: 0;
left: 0;
margin: auto;
width: 40rpx;
height: 40rpx;
overflow: hidden;
line-height: 40rpx;
text-align: center;
border-radius: 50%;
background-color: #fff;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
复制
Component({
// 组件的属性列表
properties: {
selectType: {
type: String,
value: 'checkbox'
},
radioData: {
type: Array,
value: []
},
checkboxData: {
type: Array,
value: []
},
isHidden: {
type: Boolean,
value: false
},
maxLength: {
type: Number,
value: 2
}
},
// 组件的初始数据
data: {
initRadioClass: 'radio flex-wrapper flex-direction-row',
focusRadioClass: 'radio flex-wrapper flex-direction-row active',
initCheckboxClass: 'checkbox flex-wrapper flex-direction-row',
focusCheckboxClass: 'checkbox flex-wrapper flex-direction-row active',
radioIndex: null,
checkboxIndexArr: []
},
// 组件的方法列表
methods: {
// radio选择改变触发的函数
radioChange: function (e) {
let value = e.detail.value;
this.setData({
radioIndex: value
})
this.triggerEvent('radioChange', value);
},
// checkbox选择改变触发的函数
checkboxChange: function (e) {
let value = e.detail.value;
this.setData({
checkboxIndexArr: value
})
this.triggerEvent('checkboxChange', value);
}
}
})
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
复制
其中,单选框比较简单,重点在于多选框。其中比较坑的地方就是需要手动来控制 checkboxIndexArr
的内容。
checkboxIndexArr
,所以我们自定义的样式需要通过判断当前框的 value
是不是在 checkboxIndexArr
中(切记,checkboxIndexArr中的每个值的类型都是String),小程序在wxml中绑定方法时没办法携带参数的,所以需要需要将这个函数写在 wxs
中。true
,并将其 value
放入 checkboxIndexArr
中。checked
,Boolean属性,通过控制 checked
开控制是否全选,但是,还是需要手动来添加和清空 checkboxIndexArr
的内容。checkboxIndexArr
的内容。作者个人博客:午后南杂