ByCommonSelector 通用选择器组件
一个功能强大的通用选择器组件,支持多种选择模式(下拉选择、复选框、边框选择)和丰富的功能特性。
基础用法
下拉选择模式
::: demo
vue
<template>
<div>
<by-common-selector v-model="selectedValue" :options="options" placeholder="请选择城市" @input="handleChange" />
<p>选中值: {{ selectedValue }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValue = ref('')
const options = ref([
{ id: 1, name: '何其灿', initial: 'H', status: 1 },
{ id: 2, name: '张三', initial: 'Z', status: 1 },
{ id: 3, name: '李四', initial: 'L', status: 1 },
{ id: 4, name: '王五', initial: 'W', status: 0 },
{ id: 5, name: '赵六', initial: 'Z', status: 1 },
{ id: 6, name: '孙七', initial: 'S', status: 1 },
{ id: 7, name: '周八', initial: 'Z', status: 1 },
{ id: 8, name: '吴九', initial: 'W', status: 1 },
{ id: 9, name: '郑十', initial: 'Z', status: 1 },
])
const handleChange = (value) => {
console.log('选中值变化:', value)
}
</script>
::: ### 复选框模式 ::: demo ```vue
<template>
<div>
<by-common-selector
v-model="selectedValues"
type="checkbox"
:options="options"
:multiple="true"
placeholder="请选择城市"
@input="handleChange"
/>
<p>选中值: {{ selectedValues }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValues = ref([])
const options = ref([
{ id: 1, name: '何其灿2', initial: 'H', status: 1 },
{ id: 2, name: '张三', initial: 'Z', status: 1 },
{ id: 3, name: '李四', initial: 'L', status: 1 },
{ id: 4, name: '王五', initial: 'W', status: 0 },
{ id: 5, name: '赵六', initial: 'Z', status: 1 },
{ id: 6, name: '孙七', initial: 'S', status: 1 },
{ id: 7, name: '周八', initial: 'Z', status: 1 },
{ id: 8, name: '吴九', initial: 'W', status: 1 },
{ id: 9, name: '郑十', initial: 'Z', status: 1 },
])
const handleChange = (value) => {
console.log('选中值变化:', value)
}
</script>
::: ### 边框选择模式 ::: demo ```vue
<template>
<div>
<by-common-selector
v-model="selectedValue"
type="border"
:options="options"
placeholder="请选择城市"
@input="handleChange"
/>
<p>选中值: {{ selectedValue }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValue = ref('')
const options = ref([
{ id: 1, name: '何其灿3', initial: 'H', status: 1 },
{ id: 2, name: '张三', initial: 'Z', status: 1 },
{ id: 3, name: '李四', initial: 'L', status: 1 },
{ id: 4, name: '王五', initial: 'W', status: 0 },
{ id: 5, name: '赵六', initial: 'Z', status: 1 },
{ id: 6, name: '孙七', initial: 'S', status: 1 },
{ id: 7, name: '周八', initial: 'Z', status: 1 },
{ id: 8, name: '吴九', initial: 'W', status: 1 },
{ id: 9, name: '郑十', initial: 'Z', status: 1 },
])
const handleChange = (value) => {
console.log('选中值变化:', value)
}
</script>
::: ### 带搜索栏的选择器 ::: demo ```vue
<template>
<div>
<by-common-selector
v-model="selectedValue"
:options="options"
:show-search-bar="true"
placeholder="请选择城市"
@input="handleChange"
/>
<p>选中值: {{ selectedValue }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValue = ref('')
const options = ref([
{ id: 1, name: '何其灿4', initial: 'H', status: 1 },
{ id: 2, name: '张三', initial: 'Z', status: 1 },
{ id: 3, name: '李四', initial: 'L', status: 1 },
{ id: 4, name: '王五', initial: 'W', status: 0 },
{ id: 5, name: '赵六', initial: 'Z', status: 1 },
{ id: 6, name: '孙七', initial: 'S', status: 1 },
{ id: 7, name: '周八', initial: 'Z', status: 1 },
{ id: 8, name: '吴九', initial: 'W', status: 1 },
{ id: 9, name: '郑十', initial: 'Z', status: 1 },
])
const handleChange = (value) => {
console.log('选中值变化:', value)
}
</script>
::: ### 异步加载数据 ::: demo ```vue
<template>
<div>
<by-common-selector
v-model="selectedValue"
:load-options="loadOptions"
:need-show-loading="true"
placeholder="请选择用户"
@input="handleChange"
/>
<p>选中值: {{ selectedValue }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValue = ref('')
const loadOptions = async () => {
// 模拟异步请求
await new Promise((resolve) => setTimeout(resolve, 1000))
return [
{ id: 1, name: '何其灿', initial: 'H', status: 1 },
{ id: 2, name: '张三', initial: 'Z', status: 1 },
{ id: 3, name: '李四', initial: 'L', status: 1 },
{ id: 4, name: '王五', initial: 'W', status: 0 },
{ id: 5, name: '赵六', initial: 'Z', status: 1 },
{ id: 6, name: '孙七', initial: 'S', status: 1 },
{ id: 7, name: '周八', initial: 'Z', status: 1 },
{ id: 8, name: '吴九', initial: 'W', status: 1 },
{ id: 9, name: '郑十', initial: 'Z', status: 1 },
]
}
const handleChange = (value) => {
console.log('选中值变化:', value)
}
</script>
::: ### 带后置输入框的选择器 ::: demo ```vue
<template>
<div>
<by-common-selector
v-model="selectedValue"
:options="options"
:show-suffix-input="true"
suffix-input-placeholder="请输入数量"
suffix-input-unit="个"
:suffix-input-value="suffixValue"
@input="handleChange"
@update:suffix-input-value="handleSuffixChange"
/>
<p>选中值: {{ selectedValue }}</p>
<p>数量: {{ suffixValue }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValue = ref('')
const suffixValue = ref('')
const options = ref([
{ id: 1, name: '何其灿', initial: 'H', status: 1 },
{ id: 1, name: '苹果', initial: 'P', status: 1 },
{ id: 2, name: '香蕉', initial: 'X', status: 1 },
{ id: 3, name: '橙子', initial: 'C', status: 1 },
{ id: 4, name: '葡萄', initial: 'P', status: 1 },
])
const handleChange = (value) => {
console.log('选中值变化:', value)
}
const handleSuffixChange = (value) => {
suffixValue.value = value
console.log('数量变化:', value)
}
</script>:::
API
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| value | 选择器的值 | string | number | (string | number)[] | - |
| type | 选择器类型 | 'select' | 'checkbox' | 'border' | 'select' |
| options | 选项数据 | Option[] | [] |
| loadOptions | 异步加载数据的函数 | () => Promise<Option[]> | - |
| hiddenAllOptions | 是否隐藏全部选项 | boolean | false |
| multiple | 是否多选 | boolean | false |
| placeholder | 选择器占位符 | string | '请选择' |
| size | 选择器大小 | string | 'small' |
| showSearchBar | 是否显示搜索栏 | boolean | false |
| pagination | 是否启用分页 | boolean | false |
| pageSize | 每页显示数量 | number | 50 |
| needShowLoading | 异步加载时是否显示loading | boolean | false |
| showSuffixInput | 是否显示后置输入框 | boolean | false |
| suffixInputPlaceholder | 后置输入框占位符 | string | '请输入' |
| suffixInputValue | 后置输入框的值 | string | '' |
| suffixInputUnit | 后置输入框的单位 | string | '' |
| suffixInputOptions | 后置输入框的选项 | Record<string, any> | {} |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| input | 选择值变化时触发 | (value: SelectorValue) => void |
| update:suffixInputValue | 后置输入框值变化时触发 | (value: string) => void |
| suffix-input-change | 后置输入框值变化时触发 | (value: string) => void |
Option 数据结构
typescript
interface Option {
id: number | string // 选项的唯一标识
name: string // 选项显示名称
initial?: string // 首字母(用于搜索栏)
status?: number // 状态标识
}特性说明
搜索栏功能
当启用搜索栏时(showSearchBar: true),组件会:
- 显示 A~Z 字母列表,方便快速定位
- 提供搜索框,支持按名称搜索
- 自动根据
name字段生成initial值:- 中文:提取拼音首字母并转为大写
- 非中文:直接取首字母并转为大写
分页功能
当数据量较大时,可以启用分页功能:
pagination: true- 启用分页pageSize- 设置每页显示数量- 支持展开/收起功能,自动检测是否需要展开按钮
异步加载
支持异步加载数据,适用于大数据量场景:
javascript
const loadOptions = async () => {
const response = await fetch('/api/options')
return response.json()
}后置输入框
支持在选择器右侧添加输入框,常用于数量、金额等场景:
showSuffixInput: true- 显示后置输入框suffixInputPlaceholder- 设置占位符suffixInputUnit- 设置单位suffixInputValue- 双向绑定输入值
注意事项
- 当使用
loadOptions时,options属性将被忽略 - 多选模式下,
value应该是一个数组 - 搜索栏功能若无
initial字段,则会自动生成 - 后置输入框的值需要手动绑定和更新
