微信小程序自定义select组件

405 阅读2分钟

实现微信小程序自定义select组件

在做小程序的时候发现小程序中不能像H5页面一样使用select标签,因此需要自行定义select组件来解决这个问题,如下是个人封装的自定义select组件,效果图在结尾,仅供参考,有不合理处可以指出

<!-- WXML -->
<view class="select">
    <view class="sel_title">{{title}}</view> <!-- 绑定js中数据,用来显示select文字 -->
    <view class="sel_Text" bind:tap="changeExpand"><!-- changeExpand控制展开关闭->图标切换等-->
        <text>{{selName}}</text><!-- 绑定js中数据,用来显示选中的文字 -->
        <icon class="iconfont {{isExpand?'icon-Up':'icon-Down'}}" /> <!-- 图标,可自定义 -->
    </view>
    <view class="select_list {{isExpand ? 'active' : ''}}" wx:if="{{select}}" > <!--下拉列表 -->
        <scroll-view style="max-height: 600rpx;" scroll-y="true" show-scrollbar="false" enhanced="true">
        <view class="select_item" wx:for="{{dataList}}" wx:key="keyProp" bindtap="SelectItem" data-value="{{item[keyProp]}}" data-name="{{item[valueProp]}}">{{item[valueProp]}}</view>
        </scroll-view>
    </view>
</view>

![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f93e1130d9744d20beb481e9d0cc6127~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=491&h=184&s=7742&e=png&b=fbfbfb)
// WXS
Component({
    /* 父组件传递的数据 */
    properties: {
        title: {
            type: String,
            value: ''
        },
        dataList: {
            type: Array,
            value: [
                { value: 1, name: '苹果'},
                { value: 2, name: '香蕉'},
                { value: 3, name: '橘子'},
                { value: 1, name: '苹果'},
                { value: 2, name: '香蕉'},
                { value: 3, name: '橘子'},
            ]
        },
        select: {
            type: Boolean,
            value: true
        },
        //以下俩属性可根据父组件传递过来的值绑定对应数据,可以任意数据的key-value字段,默认key为value字段,value为name字段
        keyProp: {
            type: String,
            value: 'value'
        },
        valueProp: {
            type: String,
            value: 'name'
        },
    },
    data: {
        isExpand: false,
        selName: '',
        selValue: '',
        currSelectItem: {},
        Keys: [],
       
    },
    methods: {
        changeExpand(){//下拉框展开/收缩
            let isExpand = !this.data.isExpand
            this.setData({
                isExpand: isExpand,
            })
        },
        SelectItem(e){//选择选项
            const value = e.currentTarget.dataset.value
            const name = e.currentTarget.dataset.name
            //处理传进的数据,根据外部数据将key-value字处理成外部的字段
            const currSelectItem =  this.data.dataList.filter((v,i)=>{
                return v[this.data.keyProp] == value && v[this.data.valueProp] == name
            })
            //存储选中的数据
            this.setData({
                selValue: value,
                selName: name,
                isExpand: false,
                currSelectItem: currSelectItem[0]
            })
            //触发父组件中的事件,在父组件使用bindSelcallback=‘父组件中自定义事件’
            this.triggerEvent('Selcallback',currSelectItem[0])
        }
    }
})
// WXSS 样式可以自己调整,图标需要自己引入,这里使用阿里的iconfont
@import '../../../styles/iconfont.wxss';
.select{
    display: flex;
    width: 100%;
    height: 60rpx;
    line-height: 60rpx;
    /* justify-content: space-around; */
    position: relative;
    margin: 30rpx 0 0 0 ;
}
.sel_title {
    width: 100rpx;
    height: 60rpx;
    background-color: #fff;
    margin-right: 20rpx;
    text-align: center;
}
.sel_Text {
    width: 80%;
    height: 60rpx;
    box-sizing: border-box;
    box-shadow: 1px 1px 8px 0 #ccc;
    border-radius: 10rpx;
    text-align: center;
    font-size: 28rpx;
}
.sel_Text > .icon-Up,.icon-Down {
    position: absolute;
    width: 30px;
    height: 30px;
    right: 20rpx;
}
.select_list {
    position: absolute;
    display: none;
    top: 60rpx;
    right: 20rpx;
    min-width: 220rpx;
    max-width: 420rpx;
    /* max-height: 400rpx; */
    height: 0;
    padding-top: 20rpx;
    background-color: rgb(241, 241, 241);
    box-sizing: border-box;
    z-index: 888;
    overflow: hidden;
    border-bottom-left-radius: 20rpx;
    border-bottom-right-radius: 20rpx;
    border-top: none;
    text-align: center;
}
.active {
    display: block;
    height: auto;
}
.select_item {
    padding: 8rpx 20rpx;
    font-size: 28rpx;
    box-sizing: border-box;
}

image.png