微信小程序模仿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; }