您的位置:首页 > 移动开发 > 微信开发

微信小程序 select 下拉框组件

2019-09-08 04:15 1756 查看

一、源码地址

https://github.com/imxiaoer/WeChatMiniSelect

 

二、效果图

录屏图片质量较差,所以大家会看到残影(捂脸)

 

三、组件源码

1. select.wxml

<view class="select-box">
<view class="select-current" catchtap="openClose">
<text class="current-name">{{current.name}}</text>
</view>
<view class="option-list" wx:if="{{isShow}}" catchtap="optionTap">
<text class="option"
data-id="{{defaultOption.id}}"
data-name="{{defaultOption.name}}">{{defaultOption.name}}
</text>
<text class="option"
wx:for="{{result}}"
wx:key="{{item.id}}"
data-id="{{item.id}}"
data-name="{{item.name}}">{{item.name}}
</text>
</view>
</view>

 

说明:用 catchtap 而不用 bindtap 是为了阻止事件冒泡,为了实现点击页面其他地方关闭 select, 所以在父页面(index.wxml)最外层绑定了 bindtap="close" 方法, 不阻止冒泡的话会执行父组件的 close 方法

 

2. select.js

Component({
properties: {
options: {
type: Array,
value: []
},
defaultOption: {
type: Object,
value: {
id: '000',
name: '全部城市'
}
},
key: {
type: String,
value: 'id'
},
text: {
type: String,
value: 'name'
}
},
data: {
result: [],
isShow: false,
current: {}
},
methods: {
optionTap(e) {
let dataset = e.target.dataset
this.setData({
current: dataset,
isShow: false
});

// 调用父组件方法,并传参
this.triggerEvent("change", { ...dataset })
},
openClose() {
this.setData({
isShow: !this.data.isShow
})
},

// 此方法供父组件调用
close() {
this.setData({
isShow: false
})
}
},
lifetimes: {
attached() {
// 属性名称转换, 如果不是 { id: '', name:'' } 格式,则转为 { id: '', name:'' } 格式
let result = []
if (this.data.key !== 'id' || this.data.text !== 'name') {
for (let item of this.data.options) {
let { [this.data.key]: id, [this.data.text]: name } = item
result.push({ id, name })
}
}
this.setData({
current: Object.assign({}, this.data.defaultOption),
result: result
})
}
}
})

 

说明:properties中的 key 和 text 是为了做属性名转换。比如我现在的数据结构如下:

[{
city_id: '001',
city_name: '北京'
}, {
city_id: '002',
city_name: '上海'
}, {
city_id: '003',
city_name: '深圳'
}]

而 select 组件要求的数据结构是:

[{
id: '001',
name: '北京'
}, {
id: '002',
name: '上海'
}, {
id: '003',
name: '深圳'
}]

因此我们就要将 city_id 转换成 id,city_name 转换成 name。 怎么实现属性名转换呢? 就是通过 key 和 text 这两个参数。

 

3. select.json

{
"component": true,
"usingComponents": {}
}

 

4. select.wxss

.select-box {
position: relative;
width: 100%;
font-size: 30rpx;
}

.select-current {
position: relative;
width: 100%;
padding: 0 10rpx;
line-height: 70rpx;
border: 1rpx solid #ddd;
border-radius: 6rpx;
box-sizing: border-box;
105a

}

.select-current::after {
position: absolute;
display: block;
right: 16rpx;
top: 30rpx;
content: '';
width: 0;
height: 0;
border: 10rpx solid transparent;
border-top: 10rpx solid #999;
}

.current-name {
display: block;
width: 85%;
height: 100%;
word-wrap: normal;
overflow: hidden;
}

.option-list {
position: absolute;
left: 0;
top: 76rpx;
width: 100%;
padding: 12rpx 20rpx 10rpx 20rpx;
border-radius: 6rpx;
box-sizing: border-box;
z-index: 99;
box-shadow: 0rpx 0rpx 1rpx 1rpx rgba(0, 0, 0, 0.2) inset;
background-color: #fff;
}

.option {
display: block;
width: 100%;
line-height: 70rpx;
border-bottom: 1rpx solid #eee;
}

.option:last-child {
border-bottom: none;
padding-bottom: 0;
}

 

 四、组件的使用

index.wxml

<view class="container" bindtap="close">
<view class="select-wrap">
<select id="select" options="{{options}}" key="city_id" text="city_name" bind:change="change"></select>
</view>
</view>

 

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: