Skip to content

小程序多选和单选组件的封装

🕒 Published at:

真正开发过小程序的开发者会发现,小程序里面的单选框和多选框封封装的实在不够友好,一般与 UI 都会有比较大的出入,所以下面来探讨一下单选框和多选框的封装。

效果

radio.jpg

比如我们要做一个这种样式的单选框和多选框组件,我们改怎么去处理呢?

代码

wxml

html
<!-- 判断某个元素是不是指定数组内 -->
<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

css
.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

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 的内容。

  1. 小程序多选框  在选中后会返回一个所选中的 value 的数组 checkboxIndexArr ,所以我们自定义的样式需要通过判断当前框的 value 是不是在 checkboxIndexArr 中(切记,checkboxIndexArr 中的每个值的类型都是 String), 小程序在 wxml 中绑定方法时没办法携带参数的,所以需要需要将这个函数写在 wxs 中。

  2. 如果需要有默认选中,需要单独把默认选中的框的样式激活,同时手动将默认选中的框的 checked 设置为 true ,并将其 value 放入 checkboxIndexArr 中。

  3. 如果需要做全选和全不选,需要在放置一个变量 checked ,Boolean 属性,通过控制 checked 开控制是否全选,但是,还是需要手动  来添加和清空 checkboxIndexArr 的内容。

  4. 如果需要做反选功能,需要在数据中单独设置一个控制  是否选中的 checked 属性,通过改变数据 checked 的值来改变多选框的选中效果,与上面一样,还是要手动  来添加和清空 checkboxIndexArr 的内容。

Powered by 荣顶
|
Copyright © 2018-present
|
Released under the MIT License
|
Views: