背景
项目需求要实现类似html标签 <Select/>效果,所以写了一个类似效果的自定义组件。
效果图
wxml
<view class="view-item">
<text class='item-key'>{{title}}<text style="color:red" wx:if="{{isRequired}}">*</text></text>
<view class="view-select-container">
<view class='select-value' bindtap="selectToggle">
<input value="{{value}}" name='{{name}}' disabled="{{true}}" />
<image class='img-arrow' style="width:40rpx;height:40rpx" src='/images/drop_down.png' />
</view>
<view class="view-options" wx:if="{{showOptions}}">
<cover-view class='option-item' wx:for="{{options}}" data-index="{{index}}" bindtap="selectItem">{{item[showkey]}}</cover-view>
</view>
<view class="view-out" wx:if="{{showOptions}}" bindtap="hideSelect"></view>
</view>
</view>
js
Component({
behaviors: ['wx://form-field'], //支持表单获取组件值
properties: {
//组件的名称
title: {
type: String
},
//通过form获取组件的值
name: {
type: String
},
//下拉显示的数据集合
options: {
type: Array
},
//表单组件是否必填
isRequired: {
type: Boolean
},
//外部传递的动态变量
showkey: {
type: String
}
},
data: {
showOptions: false //组件默认的展开状态
},
/**
* 组件的方法列表
*/
lifetimes: {
attached: function() {
let key = this.properties.showkey
this.setData({
value: this.properties.options[0][key] //默认选中第一个
})
},
},
methods: {
selectToggle: function(e) {
this.setData({
showOptions: !this.data.showOptions
})
},
hideSelect: function(e) {
this.setData({
showOptions: false
})
},
selectItem: function(e) {
let optionList = this.properties.options //外部传进来的数组对象
let nowIdx = e.currentTarget.dataset.index //当前点击的索引
let selectItem = optionList[nowIdx] //当前点击的内容
this.setData({
showOptions: false,
value: selectItem[this.properties.showkey]
});
let eventOption = {} // 触发事件的选项
this.triggerEvent("mySelectItem", selectItem) //组件选中回调
}
}
})
wxss
.view-item {
display: flex;
align-items: center;
padding: 2% 0%;
/* border-bottom: 1px solid #eee; */
}
.item-key {
font-size: 31rpx;
color: #666;
width: 25%;
}
.view-select-container {
width: 75%;
height: 80rpx;
position: relative;
}
.select-value {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border: 1px solid #eee;
font-size: 31rpx;
position: relative;
}
.img-arrow {
width: 28rpx;
height: 26rpx;
padding-right: 10rpx;
}
.view-options {
background-color: #fff;
display: flex;
width: 100%;
z-index: 3;
position: absolute;
flex-direction: column;
justify-content: center;
align-items: center;
}
.view-out {
position: fixed;
z-index: 2;
width: 100%;
left: 0;
top: 0;
height: 100%;
}
.option-item {
font-size: 28rpx;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
margin-top: -1px;
text-align: center;
box-sizing: border-box;
border: 1px solid #eee;
line-height: 80rpx;
height: 80rpx;
}
input {
padding-left: 3%;
font-size: 30rpx;
}
使用
json中引入自定义组件
{
"usingComponents": {
"Select": "/components/select/select"
}
}
js
Page({
data: {
optionArry: [{
"name": "香蕉",
"id": "1"
}, {
"name": "苹果",
"id": "2"
}, {
"name": "橘子",
"id": "3"
}, {
"name": "雪梨",
"id": "4"
}],
},
onLoad: function() {},
})
wxml中使用
<Select title="类别" options="{{optionArry}}" isRequired="true" bind:mySelectItem='onSelectItem' name='formkey' showkey='name' />
总结:可以动态传递对象数组在组件中显示的属性名,类似picker的range-key;使用cover-view解决当组件展开时遮住原生组件时的点击击穿问题。
最后代码片段以供学习和参考:
https://developers.weixin.qq.com/s/RwZLwImG7kcE
这个有多选吗
微信居然还没有select组件,难以置信。。。
点击组件外部 收缩选项做了吗
菩萨
多选有吗
给你磕一个
问下,怎么实现多选
哦哦,我试试
下面有textarea下拉选就有点问题
捧场