微信小程序 picker-view 自定义picker

由于微信原生picker组件不能修改样式,就本身用picker-view封装了一个bash

直接上代码微信

<!-- components/picker/picker.wxml -->
<input placeholder="{{placeholder}}" value="{{value}}" disabled="{{true}}" bindtap="showPicker" />
<view class="mask" wx:if="{{showPicker}}" bindtap="close">
  <view class="picker" animation="{{animationData}}">
    <view class="picker-header">
      <button bindtap="cancel" class="cancal">取消</button>
      <button bindtap="confirm" class="confirm">肯定</button>
    </view>
    <picker-view bindchange="change" value="{{selectValues}}" class='pickerView' indicator-style="height: 50px;" style="width: 100%; height: 300px;">
      <picker-view-column  wx:if="{{!multiSelect}}">
        <view wx:for="{{options}}" wx:key="index" style="line-height: 50px;text-align:center">
          {{label?item[label]:item}}
        </view>
      </picker-view-column>
      <picker-view-column wx:if="{{multiSelect}}"  wx:for="{{options}}" wx:for-item="option" wx:key="index">
        <view wx:for="{{option}}" wx:key="index" style="line-height: 50px;text-align:center">
          {{label?item[label]:item}}
        </view>
      </picker-view-column>
    </picker-view>
  </view>
</view>复制代码

添加validate和validatePass字段是由于项目有一个需求是须要先完成某个选择才能够继续(若是有更好的方法请你们指教)xss

// components/picker/picker.js
Component({
  behaviors: ['wx://form-field'],
  /**
   * 组件的属性列表
   */
  properties: {
    validate: {
      type: Boolean,
      value: false
    },
    placeholder: {
      type: String,
      value: '请选择'
    },
    multiSelect: {
      type: Boolean,
      value: false
    },
    label: String,
    options: Array,
    value: String,
    validatePass: {
      type: Boolean,
      value: false
    },
    title: String
  },

  /**
   * 组件的初始数据
   */
  data: {
    // value: '',
    showPicker: false,
    selectValue: 0,
    selectValues: null
  },

  /**
   * 组件的方法列表
   */
  methods: {
    showPicker() {
      // 用that取代this,防止没必要要的状况发生
      var that = this;
      // 建立一个动画实例
      var animation = wx.createAnimation({
        // 动画持续时间
        duration: 500,
        // 定义动画效果,当前是匀速
        timingFunction: 'ease'
      })
      // 将该变量赋值给当前动画
      that.animation = animation
      // 先在y轴偏移,而后用step()完成一个动画
      animation.translateY(200).step()
      // 用setData改变当前动画
      that.setData({
        // 经过export()方法导出数据
        animationData: animation.export(),

      })
      // 设置setTimeout来改变y轴偏移量,实现有感受的滑动
      setTimeout(function () {
        animation.translateY(0).step()
        that.setData({
          animationData: animation.export()
        })
      }, 50)
      if (this.data.validate) {
        if (this.data.validatePass) {
          this.setData({
            showPicker: !this.data.showPicker
          })
        } else {
          wx.showToast({
            title: this.data.title,
            icon: 'none',
            image: '',
            duration: 1500,
            mask: false,

          })
        }
      } else {
        this.setData({
          showPicker: !this.data.showPicker
        })
      }

      this.triggerEvent("show");
    },

    preventTouchMove: function () { },


    cancel() {
      this.setData({
        // value: this.data.value,
        showPicker: false
      })
      let detail = {
        value: this.data.selectValue
      }
      this.triggerEvent("cancel", detail);
    },
    confirm() {
      let arr = []
        //默认选中第一项
      if(!this.data.selectValues) {   
        if (this.data.multiSelect) {
          let opt = this.data.options
          for (let i = 0; i < opt.length; i++) {
            arr.push(0)
          }
          this.data.selectValue = arr
        } else {
          arr.push(0)
        }
        console.log(arr)
      } else {
        arr = this.data.selectValues
      }
      
      let selectValue = this.data.selectValue
      this.setData({
        value: selectValue,
        selectValue: selectValue,
        selectValues: arr,
        showPicker: false
      })
      let detail = {
        value: selectValue
      }
      this.triggerEvent("confirm", detail);
    },
    change(e) {
      console.log(e)
      let values = e.detail.value
      this.data.selectValue = this.data.multiSelect? values: values[0]
      this.data.selectValues = values
    },



  }
})复制代码
/* components/picker/picker.wxss */

.mask {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    top: 0;
    z-index: 9999;
    background: rgba(0, 0, 0, .4);
    transition: all .4s ease-in-out 0;
    pointer-events: none;
    opacity: 1;
    pointer-events: auto
}

.picker {
    position: absolute;
    width: 100%;
    height: 600rpx;
    bottom: 0;
    left: 0;
    background: #fff;
    display: flex;
    flex-direction: column;
    transition: all .4s ease-in-out 0;
}

.picker-header {
    height: 20%;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid #eeeeee;
    height: 100rpx;
    padding: 0 20rpx;
}

.cancal {
    font-size: 16px;
    font-weight: 400;
    color: rgba(51, 51, 51, 1);
}

.confirm {
    font-size: 16px;
    font-weight: 400;
    color: rgba(31, 200, 207, 1) !important;
}

button {
  background: inherit;
  border: none;
  margin: 0;
}

button:after {
    border-radius: 0rpx;
    border: none;
}复制代码

使用示例flex

<v-picker validate="{{true}}" validatePass="{{validatePass}}" title="请先选择设备类型" bind:show="showProductPicker" data-index="{{index}}" bind:confirm="productIdChange" placeholder="请选择产品类型" value="{{item.productName}}" options="{{productIds}}" label="productName"></v-picker>复制代码
showProductPicker() {
        if (!!this.data.form2.deviceTypeId || this.data.form2.deviceTypeId !== '') {
            this.setData({
                validatePass: true
            })
        } else {
            this.setData({
                validatePass: false
            })
        }
    },复制代码