1 简介

  微信小程序官方和vant框架都没有提供很方便的多选框,所以自己定义一个组件

 

2 代码 select-checkbox

2.1 json

{
  "component": true,
  "usingComponents": {
      "van-field": "@vant/weapp/field/index",
      "van-popup": "@vant/weapp/popup/index",
      "van-cell": "@vant/weapp/cell/index",
      "van-cell-group": "@vant/weapp/cell-group/index",
      "van-checkbox": "@vant/weapp/checkbox/index",
      "van-checkbox-group": "@vant/weapp/checkbox-group/index"
  }
}

 

2.2 wxss

.van-cell__value {
  text-align: left !important;
}
.cityheader {
  width: 100%;
  z-index: 5;
}
.city-cancel {
  float: left;
  margin: 20rpx;
  color: #969799;
  z-index: 11;
  position: relative;
}
.city-true {
  float: right;
  margin: 20rpx;
  color: #576b95;
  z-index: 11;
  position: relative;
}

 

2.3 wxml

2.3.1 代码

<view>
  <van-field label="{{label}}" model:value="{{ checkSelected }}" 
   placeholder="{{ place }}" border="{{ true }}" readonly
      right-icon="{{icon}}" bindtap="showPopup" />

  <van-popup show="{{ show }}" bind:close="onClose" position="bottom" custom-style="height: 60%;overflow:hidden;padding:10rpx 0rpx;">
      <!-- 取消、确定按钮 -->
      <view class="cityheader">
          <view bindtap="cancel" class="city-cancel">取消</view>
          <view bindtap="confirm" class="city-true">确定</view>
      </view>

      <!-- 内容区域 -->
      <van-checkbox-group value="{{ result }}" bind:change="onChange">
          <van-cell-group>
              <van-cell
                  wx:for="{{ list }}"
                  wx:key="index"
                  title="{{ item.label }}"
                  value-class="value-class"
                  clickable
                  data-index="{{ index }}"
                  title-width="94%" 
                  center
                  bind:click="toggle"
              >
              <van-checkbox
                  catch:tap="noop"
                  label-position="right"
                  class="checkboxes-{{ index }}"
                  name="{{ item.ind }}"
              />
              </van-cell>
          </van-cell-group>
      </van-checkbox-group>
  </van-popup>
</view>

 

2.3.2 说明

1)整体代码说明

  分为两部分,van-field就是黄色框部分,就叫选择框。van-popup 下面的就是蓝色框部分,就叫选择面板。

image

 

2)选择面板代码van-cell说明

image

 

  list:数据集合,格式:list: [{label:'黑翅土白蚁',value:'101',ind:'0'}, {label:'黄翅大白蚁',value:'102',ind:'1'}],     

     label:名称  value:value值  ind:数组的下标 

  title:选择面板展示的名称

  image

  

 

3)选择面板代码van-checkbox说明

  name:选中的值,这里采用的ind而不是value,因为获取到数组的下标,那么就可以从数字获取到对象,那么label和value值就都有了

image

 

3)选择面板van-checkbox-group代码说明

  result:选择的值,数组格式,也就是上面的选择的ind的值的数组

image

 

 

 

2.4 js

2.4.1 代码

// pages/select-checkbox/select-checkbox.js
Component({
  /**
   * 组件的属性列表
   * list的格式 list: [{label:'黑翅土白蚁',value:'101',ind:'0'}, {label:'黄翅大白蚁',value:'102',ind:'1'}],
   *    label:名称 value:value值  ind:数组下标
   */
  properties: {
      label: String, // 输入框标签
      place: String, // 输入框提示
      list: Array, // 选择器 选项
      checkSelected: { // 选择器 选项数组中 对象的value的默认key
          type: String,
          value: 'text'
      }
  },
  // 监听传入的变量,当传入的值发生变化时,触发方法
  // observers: {
  //     'checkSelected': function (val) {
  //         // val=> 就是父组件传入组件中的 tabsList 数据
  //         console.log('???:', val)
  //     }
  // },
  /**
   * 页面的初始数据
   */
  data: {
      icon:'arrow-down',  // 下拉箭头
      show: false,
      result: [],
      values:[]
  },
  /**
  * 组件的方法列表
  */
  methods: {
     // 取消
      cancel() {
          this.setData({ show: false })
      },
      // 确定
      confirm() {
          this.setData({ show: false })
          this.triggerEvent('sync', {  // 传递到组件外事件 , 返回当前选中项 对象
              value: this.data.values
          })
      },

      showPopup() {
          this.setData({ show: true })
      },
      onClose() {
          this.setData({ show: false })
      },
      onChange(event) {
        console.log('event:', event)
        var selectarr = event.detail // 选择的ind数组
        if(selectarr.length == 0){
           this.setData({
             result: [],
             values:[],
             checkSelected: ''
         })
        }else{
          var valuearr = [] // 选择的value数组
          var titlearr = [] // 选择的label数组,转换成字符串用于van-field处展示
         selectarr.forEach((point) => {
            var i = parseInt(point)
             console.log('point',i)
             console.log('properties.list[i]',this.properties.list[i])
             valuearr.push(this.properties.list[i].value)
             titlearr.push(this.properties.list[i].label)
         });
        }
       this.setData({
           result: selectarr,
           values:valuearr,
           checkSelected: titlearr.join(',')
       })
        console.log('this.data.checkSelected:', this.data.checkSelected)
        console.log('this.data.result:', this.data.result)
        console.log('this.data.values:', this.data.values)
   },
      toggle(event) {
          const { index } = event.currentTarget.dataset
          const checkbox = this.selectComponent(`.checkboxes-${index}`)
          checkbox.toggle()
      },
      noop() {},  
  },
  attached: function () {
      console.log("父组件传过来:", this.properties.checkSelected) // 可以获取父组件传过来的值
  },
})

 

 

2.4.2 说明

1) onChange

  选择或取消选择的时候调用

  这里event.detail获取到的是选择的ind数组,需要赋值给上面提到的result

  获取到了ind数组

    就可以获取到选择的对象label数组titlearr ,转换成字符串格式,赋值给checkSelected,用于van-field处展示

    也可以获取到选择的对象的value数组valuearr :用于返回给父组件

onChange(event) {
        console.log('event:', event)
        var selectarr = event.detail // 选择的ind数组
        if(selectarr.length == 0){
           this.setData({
             result: [],
             values:[],
             checkSelected: ''
         })
        }else{
          var valuearr = [] // 选择的value数组
          var titlearr = [] // 选择的label数组,转换成字符串用于van-field处展示
         selectarr.forEach((point) => {
            var i = parseInt(point)
             console.log('point',i)
             console.log('properties.list[i]',this.properties.list[i])
             valuearr.push(this.properties.list[i].value)
             titlearr.push(this.properties.list[i].label)
         });
        }
       this.setData({
           result: selectarr,
           values:valuearr,
           checkSelected: titlearr.join(',')
       })
        console.log('this.data.checkSelected:', this.data.checkSelected)
        console.log('this.data.result:', this.data.result)
        console.log('this.data.values:', this.data.values)
   },

 

3 使用

3.1 json引入

"select-checkbox": "/components/select-checkbox/select-checkbox"

 

3.2 wxml

 <view class="search-tt2 ,require-label:before">多选: </view>
    <view class="search-kk st">
      
      <select-checkbox style="width:100%" label="" title-width="70" place="请选择白蚁种类" list="{{ list }}" bind:sync="getSelectBox" checkSelected=""></select-checkbox>
    
    </view>

 

3.3 js

  data数据

checkSelected: '',
    list: [{label:'黑翅土白蚁',value:'101',ind:'0'}, {label:'黄翅大白蚁',value:'102',ind:'1'}],

  回调函数

  

  // 获取选中的值
  getSelectBox: function(e) {
    // 打印选中项,就是选择的对象的value数组
    console.log("11111111:", e.detail.value)
    this.setData({
        checkSelected: e.detail.value
    })
  }

 

3.4 css

.search-tt2 {
  float: left;
  width: 180rpx;
  height: 80rpx;
  line-height: 80rpx;
  font-size: 32rpx;
  color: #333;
  margin-left: 70rpx; 
  margin-top: 10px;
}

.search-kk {
  width: calc(80% - 150rpx);
  height: 80rpx;
  border: 1px solid rgb(169, 167, 167);
  box-sizing: border-box;
  padding: 0 20rpx;
  line-height: 70rpx;
  font-size: 28rpx;
  color: #333;
  overflow-x: hidden;
  border-radius: 10rpx;
}

.st {
  margin-top: 20rpx;
}