# Select 选择器

选择器组件,支持单选和多选, 需要与com-option组件搭配使用

# 基本使用

默认为单选

<com-select v-model="gender">
    <com-option value="1" label=""></com-option>
    <com-option value="2" label=""></com-option>
</com-select>

<script>
    export default {
        data(){
            return {
                gender: '1',
            }
        }
    }
</script>

多选

<com-select v-model="colors" multiple>
    <com-option value="1" label="红色" class="mgr-10"></com-option>
    <com-option value="2" label="绿色" class="mgr-10"></com-option>
    <com-option value="3" label="蓝色" class="mgr-10"></com-option>
    <com-option value="4" label="白色" class="mgr-10"></com-option>
    <com-option value="5" label="粉色" class="mgr-10"></com-option>
</com-select>

<script>
    export default {
        data(){
            return {
                colors: '',
            }
        }
    }
</script>

简单设置样式

<com-select v-model="gender">
    <com-option value="1" label="" :border-radius="[40,0,0,40]" active-color="green"></com-option>
    <com-option value="2" label="" :border-radius="[0,40,40,0]" active-color="green"></com-option>
</com-select>

自定义选项样式

组件设置className属性,绑定样式类名;

如果使用了scoped,则需要在类名前加上/deep/

如果class中某个样式不生效,则可以加上!important提升优先级

<com-select v-model="fruit" multiple className="fruit-select">
    <com-option value="1" label="苹果" className="fruit-option"></com-option>
    <com-option value="2" label="香蕉" className="fruit-option"></com-option>
    <com-option value="3" label="芒果" className="fruit-option"></com-option>
    <com-option value="4" label="桃子" className="fruit-option"></com-option>
    <com-option value="5" label="西瓜" className="fruit-option"></com-option>
    <com-option value="6" label="李子" className="fruit-option"></com-option>
    <com-option value="7" label="火龙果" className="fruit-option"></com-option>
    <com-option value="8" label="葡萄" className="fruit-option"></com-option>
</com-select>

<style lang="scss" scoped>
/deep/ .fruit-select{
	display: flex;
	flex-wrap: wrap;
}

/deep/ .fruit-option{
	margin-right: 10rpx;
	padding: 10rpx 16rpx;
	border-radius: 10rpx;
	border: 1rpx solid #3B97FF;
	color: #3B97FF;
	margin-bottom: 10rpx;
	flex-shrink: 0;
	
	&.com-option__active{
		color: white;
		background-color: #3B97FF !important;
	}
	
	&.com-option__disabled{
		background-color: #ccc;
	}
}
</style>

显示图标

<com-select v-model="agree">
    <com-option value="1" label="我已同意" icon="checkbox-circle" :border="false"></com-option>
    <text class="txt-main">《用户协议》</text>
</com-select>

<script>
    export default {
        data(){
            return {
                agree: '',
            }
        }
    }
</script>

只读模式

<com-select v-model="gender" readonly>
    <com-option value="1" label="" :border-radius="[40,0,0,40]" active-color="green"></com-option>
    <com-option value="2" label="" :border-radius="[0,40,40,0]" active-color="green"></com-option>
</com-select>

弹窗选择

如果需要使用内置弹窗,则可以加上popup属性。该弹窗依赖com-popup组件,关于内置弹窗的简单设置请参见下方API.

<com-select v-model="xz" popup>
    <com-option value="1" label="水瓶座"></com-option>
    <com-option value="2" label="双鱼座"></com-option>
    <com-option value="3" label="白羊座"></com-option>
    <com-option value="4" label="金牛座"></com-option>
    <com-option value="5" label="巨蟹座"></com-option>
    <com-option value="6" label="双子座"></com-option>
    <com-option value="7" label="处女座"></com-option>
    <com-option value="8" label="狮子座"></com-option>
    <com-option value="9" label="天秤座"></com-option>
    <com-option value="10" label="天蝎座"></com-option>
    <com-option value="11" label="射手座"></com-option>
    <com-option value="12" label="摩羯座"></com-option>
</com-select>

<script>
    export default {
        data(){
            return {
                xz: '',
            }
        }
    }
</script>

# 数据驱动

根据后端接口需要,可以通过v-model绑定不同类型的值

如果选中某一项,则会option的value值赋值给select的v-model所绑定的变量

# 单选数据

(1). 如果实现单选逻辑,且后端只需要选项中的id值,这时可以让v-model绑定的变量是字符串,com-option中的value绑定选项的id值

<com-select v-model="userId" popup>
    <!-- 选中后 v-model将得到 选项value绑定的值 -->
    <com-option :value="item.id" :label="item.name" v-for="(item, index) in userList" :key="item.id"></com-option>
</com-select>

<script>
    data(){
        return {
            userId: '',
            userList: [
                { id: 1, name: '张三' },
                { id: 2, name: '李四' },
                { id: 3, name: '王五' },
                { id: 4, name: '赵六' },
            ],
        }
    }
</script>

(2). 如果实现单选逻辑,且需要获取选项整个对象,这时可以让v-model绑定变量为对象类型,com-option中的value绑定选项整个对象。

注意对象类型请务必加上value-key属性,该值表示将对象中的某个字段作为对象唯一标识,以告诉组件如何区分不同对象。
<com-select v-model="user" popup value-key="id">
    <com-option :value="item" :label="item.name" v-for="(item, index) in userList" :key="item.id"></com-option>
</com-select>

<script>
    data(){
        return {
            user: {},
            userList: [
                { id: 1, name: '张三' },
                { id: 2, name: '李四' },
                { id: 3, name: '王五' },
                { id: 4, name: '赵六' },
            ],
        }
    }
</script>

# 多选数据

(1). 如果实现多选逻辑,且后端只需要选项id数组(逗号分隔的字符串),这时可以让v-model绑定的变量是字符串,com-option中的value绑定选项的id值

<com-select v-model="userIds" popup multiple>
    <com-option :value="item.id" :label="item.name" v-for="(item, index) in userList" :key="item.id"></com-option>
</com-select>

<script>
    data(){
        return {
            userIds: '', //声明为字符串类型,将得到逗号分隔的字符串
            userList: [
                { id: 1, name: '张三' },
                { id: 2, name: '李四' },
                { id: 3, name: '王五' },
                { id: 4, name: '赵六' },
            ],
        }
    }
</script>

(2). 如果实现多选逻辑,且后端只需要选项id数组,这时可以让v-model绑定的变量是数组类型,com-option中的value绑定选项的id值

<com-select v-model="userIds" popup multiple>
    <com-option :value="item.id" :label="item.name" v-for="(item, index) in userList" :key="item.id"></com-option>
</com-select>

<script>
    data(){
        return {
            userIds: [], //声明为数组类型
            userList: [
                { id: 1, name: '张三' },
                { id: 2, name: '李四' },
                { id: 3, name: '王五' },
                { id: 4, name: '赵六' },
            ],
        }
    }
</script>

(3). 如果需要拿到对象数组,这时可以让v-model绑定的变量是数组类型,com-option中的value绑定选项整个对象

注意对象类型请务必加上value-key属性,该值表示将对象中的某个字段作为对象唯一标识,以告诉组件如何区分不同对象。
<com-select v-model="users" popup multiple value-key="id">
    <com-option :value="item" :label="item.name" v-for="(item, index) in userList" :key="item.id"></com-option>
</com-select>

<script>
    data(){
        return {
            users: [], //声明为数组类型
            userList: [
                { id: 1, name: '张三' },
                { id: 2, name: '李四' },
                { id: 3, name: '王五' },
                { id: 4, name: '赵六' },
            ],
        }
    }
</script>

# 分页和搜索方案

选项通常是动态数据,有时候需要分页和搜索,这里我们可以自行实现列表的动态渲染,也可以借助com-scroll-view组件实现分页等常用功能

<com-select ref="user-select" v-model="users" popup multiple value-key="id">
    <view class="flex-col h-all">
        <view class="pd-20 no-shrink">
            <com-input mode="search" v-model="param.name" placeholder="输入姓名进行搜索" 
            border clearable @confirm="handleSearch"></com-input>
        </view>
        
        <com-scroll-view ref="list" v-model="list" req="UserList" :param="param">
            <com-option :value="item" :label="item.name" className="xz-option" 
            v-for="(item, index) in list" :key="'user2'+item.id"></com-option>
        </com-scroll-view>
    </view>
</com-select>

<script>
    data(){
        return {
            users: [],
            list: [],
        }
    },
    onLoad() {
        this.getList()
    },

    methods: {

        getList(){
            setTimeout(()=>{
                this.$refs['list'].load()
            }, 300)
        },

        handleSearch(){
            
            let oldList = JSON.parse(JSON.stringify(this.list))
            
            // 获取已选择的选项,防止搜索后丢失原来已被选中的选项
            let activeOptions = oldList.filter((item)=>{
                // 可以通过select组件方法快速判断是否已被选中
                return this.$refs['user-select'].isActive(item.id)
            })
            
            // 搜索获取数据接口
            UserList({
                ...this.param,
                current: 1,
                size: 10,
            }).then((res)=>{
                this.list = []
                // 过滤掉重复数据,以免引起key值重复
                let list = res.data.filter(item=>{
                    return !this.$refs['user-select'].isActive(item.id)
                })

                this.list = list.concat(activeOptions)
            })
        },
    }
</script>

# 自定义布局

option的插槽可以编写任意内容,有时候选项中会需要展示很多其他字段。

<view class="" style="height: 100vh;display: flex;flex-direction: column">
    <com-scroll-view ref="companyList" v-model="companyList" req="CompanyList">
        <com-select v-model="company" value-key="id" className="company-select">
            <com-option :value="item" :label="item.name" 
                v-for="(item, index) in companyList" :key="item.id" 
                icon="checkbox-circle" className="company-option">
                <view class="">
                    <text>{{ item.name }}</text>
                </view>
                <view class="txt-gray-dark font-26 flex space-between">
                    <text>电话:{{ item.phone }}</text>
                    <text>地址:{{ item.address }}</text>
                </view>
            </com-option>
        </com-select>
    </com-scroll-view>
</view>

<script>
    data(){
        return {
            company: {},
            companyList: [],
        }
    },

    methods: {
        getList(){
            setTimeout(()=>{
				this.$refs['companyList'].load()
			}, 500)
        }
    }
</script>

# API

# com-select Props

属性名 说明 类型 必填 默认值
value 表单值,使用v-model双向数据绑定
如果是字符串类型,多选时应该传入逗号分隔
String / Array / Object -
multiple 是否多选 Boolean false
readonly 是否只读 Boolean false
limit 最大选择个数, 0表示不限制 Number 0
valueKey 作为 value 唯一标识的键名,绑定值为对象类型时必填 String value
placeholder 占位文本 String 请选择
emptyText 只读模式空文本 String 未选择
separator 只读模式多选时的分隔符 String ,
tagColor 被选中时颜色 将作为选中时背景/边框/图标的颜色 String 主题色
showTagClose 是否显示标签后的关闭按钮 Boolean true
customStyle 自定义样式 Object {}
tagStyle 标签样式 Object {}
className 自定义样式类名称,使用此属性时,所有默认样式将被取消 String -
popup 是否将选项作为弹出层 Boolean false
popupHeight 弹出层高度 String / Number 60vh
showTag 是否显示已选中标签 Boolean true

# com-select Events

事件 说明 回调参数
change v-model值改变事件
参数一: v-model绑定的值 参数二: v-model值对应的选项,多选时为数组类型
confirm 弹窗点击确定
参数一: v-model绑定的值 参数二: v-model值对应的选项,多选时为数组类型

# com-option Props

属性名 说明 类型 必填 默认值
value 唯一主键(通常是传给后端的值) -
label 页面显示的内容 -
disabled 是否禁用 Boolean false
icon 勾选图标
支持checkbox checkbox-circle radio tick
String -
iconSize 图标大小 String / Number -
iconAfter 是否将图标显示在末尾 Boolean false
bgColor 默认的背景颜色 String #F8F8F8
color 默认的文本颜色 String #000
activeColor 被选中时颜色 将作为选中时背景/边框/图标的颜色 String 主题色
disabledColor 禁用时的颜色 将作为选中时背景/边框/图标的颜色 String #C4C9DB
border 是否显示边框 Boolean false
borderRadius 圆角大小 Array / String 10
customStyle 自定义非选中样式 Object {}
activeStyle 自定义被选中样式 Object {}
disableStyle 被禁用样式 Object {}
className 自定义样式类名称,使用此属性时,所有默认样式将被取消 String -
上次更新时间: 2/14/2023, 11:17:40 AM