更新记录

V1.0.0(2024-02-26)

初版:支持多选、单选、可搜索、可清除功能


平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
app-vue app-nvue × × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序
× × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari

前提需要导入 uni-ui 组件库,直接在插件市场搜索通过Hbuilder导入即可。也可npm导入 否则看不到清除按钮和搜索框

极简使用示例

<!-- 多选组件 -->
<curry-multi-select title="请选择" :show="countrySelectMultiple.show" :columns="countrySelectMultiple.columns"
  :defaultIndex="countrySelectMultiple.index"
  @confirm="confirmMultiple(countrySelectMultiple, 'country', $event)"
  @cancel="countrySelectMultiple.show = false"></curry-multi-select>

属性:

属性 说明 类型 默认值
title 标题 string
show 是否弹出筛选框 Boolean false
columns 数据列表 Array [{"label": "中国","value": "cn"}]
defaultIndex 默认选中 Array []
isMultiSelect 是否多选 Boolean true

事件

事件名 说明 参数 示例
@confirm 选中数据确认 数据,prop名称,event @confirm="confirmMultiple(countrySelectMultiple, 'country', $event)"
@cancel 取消选择

示例:

<template>
    <view>
        <view class="filter-container">
            <!-- 下拉框多选 listQuery.country 为true, class 为 select + selected 
            @tap 比 @click 更敏感是 uni-app 特有的指令,可以更快地响应用户的触摸操作 -->
            <view class="item">
                <view :class="['select', listQuery.country.length > 0 ? 'selected' : '']"
                    @tap="handleMultiple(countrySelectMultiple, listQuery.country)">
                    {{listQuery.country.length > 0 ? listQuery.country.toString() : '国家'}}
                </view>
                <!-- 模拟清除按钮 -->
                <uni-icons v-if="listQuery.country.length > 0" type="clear" size="22" color="#999" class="close-btn"
                    @tap="clearSelection(countrySelectMultiple, 'country')"></uni-icons>
                <uni-icons v-else type="down" size="15" color="#999" class="close-btn"
                    @tap="handleMultiple(countrySelectMultiple, listQuery.country)"></uni-icons>

                <!-- 多选组件 -->
                <curry-multi-select title="请选择" :show="countrySelectMultiple.show" :columns="countrySelectMultiple.columns"
                    :defaultIndex="countrySelectMultiple.index"
                    @confirm="confirmMultiple(countrySelectMultiple, 'country', $event)"
                    @cancel="countrySelectMultiple.show = false"></curry-multi-select>
            </view>

            <!-- offer名称单选 -->
            <view class="item">
                <view :class="['select', listQuery.offerName != '' ? 'selected' : '']"
                    @tap="handleMultiple(offerNameSelectMultiple, listQuery.offerName)">
                    {{listQuery.offerName != ''? listQuery.offerName : 'offer名称'}}
                </view>
                <uni-icons v-if="listQuery.offerName != ''" type="clear" size="22" color="#999" class="close-btn"
                    @tap="clearSelection(offerNameSelectMultiple, 'offerName')"></uni-icons>
                <uni-icons v-else type="down" size="15" color="#999" class="close-btn"
                    @tap="handleMultiple(offerNameSelectMultiple, listQuery.offerName)"></uni-icons>

                <curry-multi-select title="请选择" :show="offerNameSelectMultiple.show" :columns="offerNameSelectMultiple.columns"
                    :defaultIndex="offerNameSelectMultiple.index"
                    :isMultiSelect="false"
                    @confirm="confirmMultiple(offerNameSelectMultiple, 'offerName', $event)"
                    @cancel="offerNameSelectMultiple.show = false"></curry-multi-select>
            </view>
        </view>
    </view>
</template>

<script>

    export default {
        data() {
            return {
                countrySelectMultiple: {
                    show: false,
                    index: [],
                    columns: [
                        {
                            "label": "印尼",
                            "value": "id"
                        },
                        {
                            "label": "中国",
                            "value": "cn"
                        },
                        {
                            "label": "日本",
                            "value": "jp"
                        },
                        {
                            "label": "马来西亚",
                            "value": "my"
                        },
                        {
                            "label": "美国",
                            "value": "usa"
                        }
                    ]
                },
                offerNameSelectMultiple: {
                    show: false,
                    index: [],
                    columns: [
                        {
                            "label": "offer1",
                            "value": "1"
                        },
                        {
                            "label": "offer2",
                            "value": "2"
                        },
                        {
                            "label": "offer3",
                            "value": "3"
                        },
                    ]
                },
                selectedRows: [], // 存储选中的行数据
                selectedRowIds: [], // 存储选中的行的id
                listQuery: {
                    country:[],
                    offerName: ''
                }
            }
        },
        onLoad() {
        },
        methods: {
            clearSelection(selectMultiple, prop) {
                // 阻止事件冒泡
                selectMultiple.index = []
                if (prop === 'country') {
                    this.listQuery.country = [];
                } else if (prop === 'offerName') {
                    this.listQuery.offerName = '';
                }
            },
            handleMultiple(selectMultiple, val) {
                console.log(val)
                if (typeof val === 'string') {
                    let arr = [];
                    if (val !== '') {
                        arr.push(val)
                    }
                    selectMultiple.index = arr;
                } else {
                    selectMultiple.index = val || [];
                }
                selectMultiple.show = true;
            },
            confirmMultiple(selectMultiple, prop, e) {
                // 直接传递 this.listQuery.country 属性过来无法绑定 country 值, 传递的是副本不是引用只能修改 listQuery 对象
                if (prop === 'country') {
                    this.listQuery.country = [];
                    e.value.forEach(item => {
                        this.listQuery.country.push(item);
                    })
                } else if (prop === 'offerName') {
                    this.listQuery.offerName = '';
                    this.listQuery.offerName = e.value[0]
                }
                selectMultiple.show = false;
            }
            }
    }
</script>

<style>

    .filter-container {
        background-color: white;
        margin: 10px;
    }

    .item {
        width: 100%;
        padding: 10rpx 0;
        position: relative;
        /* 添加这行,为 .close-btn 提供定位上下文 */
        display: flex;
        /* 使用flex布局来水平排列 .select 和 .close-btn */
        align-items: center;
        /* 垂直居中子元素 */

        .select {
            flex-grow: 1;
            /* .select 占据剩余空间 */
            border: 1px solid #dadbde;
            padding-top: 6px;
            padding-bottom: 6px;
            padding-left: 9px;
            padding-right: 9px;
            border-radius: 4px;
            font-size: 12px;
            box-sizing: border-box;
            color: #6a6a6a;
            line-height: 26px;

            &.selected {
                color: black;
                font-size: 15px;
            }
        }

        .close-btn {
            /* width: 10%; 不再需要设置宽度 */
            position: absolute;
            /* 绝对定位 */
            right: 8px;
            /* 右侧定位 */
            top: 50%;
            /* 顶部50%定位 */
            transform: translateY(-50%);
            /* Y轴偏移-50%,确保垂直居中 */
            color: red;
            /* X按钮的颜色 */
            cursor: pointer;
            /* 鼠标悬停时变成手型图标 */
        }
    }
</style>

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问