真正开发过小程序的开发者会发现,小程序里面的单选框和多选框封封装的实在不够友好,一般与UI都会有比较大的出入,所以下面来探讨一下单选框和多选框的封装。
效果
比如我们要做一个这种样式的单选框和多选框组件,我们改怎么去处理呢?
代码
wxml
<!-- 判断某个元素是不是指定数组内 --> <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>
wxss
.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; }
javascript
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); } } })
分析
其中,单选框比较简单,重点在于多选框。其中比较坑的地方就是需要手动来控制 checkboxIndexArr
的内容。
小程序多选框在选中后会返回一个所选中的value的数组
checkboxIndexArr
,所以我们自定义的样式需要通过判断当前框的value
是不是在checkboxIndexArr
中(切记,checkboxIndexArr中的每个值的类型都是String),小程序在wxml中绑定方法时没办法携带参数的,所以需要需要将这个函数写在wxs
中。如果需要有默认选中,需要单独把默认选中的框的样式激活,同时手动将默认选中的框的checked设置为
true
,并将其value
放入checkboxIndexArr
中。如果需要做全选和全不选,需要在放置一个变量
checked
,Boolean属性,通过控制checked
开控制是否全选,但是,还是需要手动来添加和清空checkboxIndexArr
的内容。如果需要做反选功能,需要在数据中单独设置一个控制是否选中的checked属性,通过改变数据checked的值来改变多选框的选中效果,与上面一样,还是要手动来添加和清空
checkboxIndexArr
的内容。
个人博客:午后南杂
来源:https://www.cnblogs.com/luanhewei/p/9483921.html