微信小程序模仿select组件

js

const computedBehavior = require("../../utils/computed");

Component({
  behaviors: [computedBehavior],
  /**
   * 组件的属性列表
   */
  properties: {
    // 选项数组
    options: {
      type: Array,
      value: [],
      observer(options) {
        this.setData({
          options
        })
      }
    },
    // 值的字段
    valueKey: {
      type: String,
      value: 'value'
    },
    // 展示用的text的字段
    textKey: {
      type: String,
      value: 'text'
    },
    value: {
      type: Number | String,
      value: ''
    },
    defaultText: {
      type: String,
      value: '请选择'
    }
  },
  /**
   * 组件的初始数据
   */
  data: {
    selectShow: false, // 初始option不显示
    text: "", // 初始内容
    animationData: {} // 右边箭头的动画
  },
  computed: {
    showText() {
      const text = this.data.options.find(x => x[this.properties.valueKey] === this.properties.value) || {}
      return text[this.properties.textKey] || this.data.text || this.properties.defaultText
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    //option的显示与否
    selectToggle() {
      const nowShow = this.data.selectShow;//获取当前option显示的状态
      //创建动画
      const animation = wx.createAnimation({
        timingFunction: "ease"
      })
      this.animation = animation;
      if (nowShow) {
        animation.rotate(0).step();
        this.setData({
          animationData: animation.export()
        })
      } else {
        animation.rotate(180).step();
        this.setData({
          animationData: animation.export()
        })
      }
      this.setData({
        selectShow: !nowShow
      })
    },
    //设置内容
    selectChange({ currentTarget }) {
      const index = currentTarget.dataset.index;
      const currentItem = this.properties.options[index]
      this.animation.rotate(0).step();
      this.setData({
        selectShow: false,
        text: currentItem[this.properties.textKey],
        animationData: this.animation.export()
      })
      this.triggerEvent("change", currentItem)
    },
    // 重置
    reset() {
      this.animation.rotate(0).step();
      this.setData({
        selectShow: false,
        text: "",
        animationData: this.animation.export()
      })
      this.triggerEvent("change", {})
    }
  }
})

  

wxml

<view class="com-select-wrap">
  <view class="com-select-content" bindtap="selectToggle">
    <view class="com-select-value">{{showText}}</view>
    <image src="/img/icon_down.png" class="com-select-arrow" animation="{{animationData}}" />
  </view>
  <!-- cover-view防止点击传透 -->
  <cover-view class="com-select-list" wx:if="{{selectShow}}">
    <cover-view
      wx:for="{{options}}"
      data-index="{{index}}"
      wx:key
      class="com-select-item {{item[valueKey]===value?'active':''}}"
      catch:tap="selectChange"
    >{{item[textKey]}}</cover-view>
  </cover-view>
</view>

 wxss

.com-select-wrap {
  width: 100%;
  border: 1px solid #f5f5f5;
  border-radius: 8rpx;
  position: relative;
  font-size: 28rpx;
}
.com-select-content {
  padding: 0 30rpx;
  display: flex;
  align-items: center;
  border-radius: 8rpx;
  background-color: #fff;
  height: 72rpx;
  line-height: 72rpx;
}
.com-select-arrow {
  width: 20rpx;
  height: 12rpx;
  transition: all 0.3s ease;
}
.com-select-value {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.com-select-list {
  position: absolute;
  top: 72rpx;
  left: 0;
  right: 0;
  z-index: 3;
  padding: 0 30rpx;
  box-sizing: border-box;
  border: 1px solid #f5f5f5;
  border-radius: 8rpx;
  overflow-y: auto;
  max-height: 420rpx;
  background-color: #fff;
  box-shadow: 0 10rpx 16rpx 0 rgba(0, 0, 0, 0.1);
}
.com-select-item {
  height: 84rpxpx;
  line-height: 84rpx;
  border-bottom: 1px solid #f5f5f5;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.com-select-item.active {
  color: #fece2b;
}
.com-select-item:last-of-type {
  border-bottom: 0 none;
}

 

posted @ 2019-12-05 18:28  wangwht  阅读(905)  评论(0编辑  收藏  举报