ByBatchQuerySelector 批量查询选择器组件
一个功能强大的批量查询选择器组件,支持批量输入ID或名称进行快速选择,适用于大量数据的快速筛选场景。
基础用法
基础多选模式
::: demo
vue
<template>
<div>
<by-batch-query-selector
v-model="selectedValues"
:options="options"
placeholder="请选择用户"
@change="handleChange"
/>
<p>选中值: {{ selectedValues }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValues = ref([])
const options = ref([
{ id: 1, name: '张三', department: '技术部' },
{ id: 2, name: '李四', department: '产品部' },
{ id: 3, name: '王五', department: '设计部' },
{ id: 4, name: '赵六', department: '运营部' },
{ id: 5, name: '孙七', department: '技术部' },
{ id: 6, name: '周八', department: '产品部' },
{ id: 7, name: '吴九', department: '设计部' },
{ id: 8, name: '郑十', department: '运营部' },
])
const handleChange = (value) => {
console.log('选中值变化:', value)
}
</script>
::: ### 单选模式 ::: demo ```vue
<template>
<div>
<by-batch-query-selector
v-model="selectedValue"
:options="options"
:multiple="false"
placeholder="请选择用户"
@change="handleChange"
/>
<p>选中值: {{ selectedValue }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValue = ref('')
const options = ref([
{ id: 1, name: '张三', department: '技术部' },
{ id: 2, name: '李四', department: '产品部' },
{ id: 3, name: '王五', department: '设计部' },
{ id: 4, name: '赵六', department: '运营部' },
{ id: 5, name: '孙七', department: '技术部' },
])
const handleChange = (value) => {
console.log('选中值变化:', value)
}
</script>
::: ### 异步加载数据 ::: demo ```vue
<template>
<div>
<by-batch-query-selector
v-model="selectedValues"
:load-options="loadOptions"
:auto-load="true"
placeholder="请选择用户"
@change="handleChange"
@options-loaded="handleOptionsLoaded"
/>
<p>选中值: {{ selectedValues }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValues = ref([])
const loadOptions = async () => {
// 模拟异步请求
await new Promise((resolve) => setTimeout(resolve, 1000))
return [
{ id: 1, name: '张三', department: '技术部' },
{ id: 2, name: '李四', department: '产品部' },
{ id: 3, name: '王五', department: '设计部' },
{ id: 4, name: '赵六', department: '运营部' },
{ id: 5, name: '孙七', department: '技术部' },
{ id: 6, name: '周八', department: '产品部' },
{ id: 7, name: '吴九', department: '设计部' },
{ id: 8, name: '郑十', department: '运营部' },
]
}
const handleChange = (value) => {
console.log('选中值变化:', value)
}
const handleOptionsLoaded = (options) => {
console.log('选项加载完成:', options)
}
</script>
::: ### 自定义映射函数 ::: demo ```vue
<template>
<div>
<by-batch-query-selector
v-model="selectedValues"
:options="options"
:custom-map-function="customMapFunction"
placeholder="请选择用户"
@change="handleChange"
@batch-input-complete="handleBatchComplete"
/>
<p>选中值: {{ selectedValues }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValues = ref([])
const options = ref([
{ id: 1, name: '张三', code: 'ZS001', department: '技术部' },
{ id: 2, name: '李四', code: 'LS002', department: '产品部' },
{ id: 3, name: '王五', code: 'WW003', department: '设计部' },
{ id: 4, name: '赵六', code: 'ZL004', department: '运营部' },
{ id: 5, name: '孙七', code: 'SQ005', department: '技术部' },
])
// 自定义映射函数,支持按工号匹配
const customMapFunction = (inputValues, inputType, optionsList) => {
if (inputType === 'code') {
return optionsList
.filter((item) => inputValues.some((input) => String(item.code).toLowerCase() === String(input).toLowerCase()))
.map((item) => item.id)
}
return []
}
const handleChange = (value) => {
console.log('选中值变化:', value)
}
const handleBatchComplete = (data) => {
console.log('批量输入完成:', data)
}
</script>
::: ### 禁用选项 ::: demo ```vue
<template>
<div>
<by-batch-query-selector
v-model="selectedValues"
:options="options"
:disabled-method="isOptionDisabled"
placeholder="请选择用户"
@change="handleChange"
/>
<p>选中值: {{ selectedValues }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValues = ref([])
const options = ref([
{ id: 1, name: '张三', status: 1, department: '技术部' },
{ id: 2, name: '李四', status: 0, department: '产品部' },
{ id: 3, name: '王五', status: 1, department: '设计部' },
{ id: 4, name: '赵六', status: 0, department: '运营部' },
{ id: 5, name: '孙七', status: 1, department: '技术部' },
])
// 自定义禁用判断方法
const isOptionDisabled = (option) => {
return option.status === 0
}
const handleChange = (value) => {
console.log('选中值变化:', value)
}
</script>
::: ### 自定义样式 ::: demo ```vue
<template>
<div>
<by-batch-query-selector
v-model="selectedValues"
:options="options"
:max-width="400"
:popover-width="350"
:size="'default'"
placeholder="请选择用户"
@change="handleChange"
/>
<p>选中值: {{ selectedValues }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedValues = ref([])
const options = ref([
{ id: 1, name: '张三', department: '技术部' },
{ id: 2, name: '李四', department: '产品部' },
{ id: 3, name: '王五', department: '设计部' },
{ id: 4, name: '赵六', department: '运营部' },
{ id: 5, name: '孙七', department: '技术部' },
])
const handleChange = (value) => {
console.log('选中值变化:', value)
}
</script>API
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定值 | Array<string | number> | string | number | [] |
| options | 数据源 | Option[] | [] |
| loadOptions | 异步加载数据源 | (params?: Record<string, unknown>) => Promise<Option[]> | - |
| autoLoad | 是否自动加载数据(首次获取焦点时) | boolean | true |
| valueKey | 值字段名 | string | 'id' |
| labelKey | 标签字段名 | string | 'name' |
| disabledKey | 禁用字段名 | string | 'disabled' |
| disabledMethod | 禁用条件,自定义函数判断选项是否禁用 | (option: Option) => boolean | - |
| multiple | 是否多选 | boolean | true |
| collapseTags | 是否折叠标签 | boolean | true |
| placeholder | 占位符 | string | '请选择' |
| disabled | 是否禁用 | boolean | false |
| clearable | 是否可清空 | boolean | true |
| size | 大小 | string | 'mini' |
| maxWidth | 最大宽度 | string | number | '100%' |
| popoverWidth | 弹窗宽度 | string | number | '300' |
| customMapFunction | 自定义映射函数 | (inputValues: string[], inputType: string, optionsList: Option[]) => Array<string | number> | - |
| pageSize | 每页加载数量 | number | 100 |
| initialPageCount | 初始加载页数 | number | 1 |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| update:modelValue | 绑定值变化时触发 | (value: Array<string | number> | string | number) => void |
| change | 选择值变化时触发 | (value: Array<string | number> | string | number) => void |
| batch-selector-focus | 获取焦点时触发 | (event: Event) => void |
| options-loaded | 选项加载完成时触发 | (options: Option[]) => void |
| options-load-error | 选项加载失败时触发 | (error: unknown) => void |
| batch-input-complete | 批量输入完成时触发 | (data: BatchInputData) => void |
Option 数据结构
typescript
interface Option {
[key: string]: string | number
}BatchInputData 数据结构
typescript
interface BatchInputData {
inputValues: string[] // 输入的原始值数组
matchedValues: Array<string | number> // 匹配到的值数组
matchedItems: Option[] // 匹配到的完整选项对象数组
type: string // 输入类型('id' 或 'name')
}特性说明
自定义映射函数
支持自定义批量输入的映射逻辑:
javascript
const customMapFunction = (inputValues, inputType, optionsList) => {
// 自定义匹配逻辑
return matchedValues
}禁用选项支持
支持禁用特定选项:
disabledKey:指定禁用字段名disabledMethod:自定义禁用判断函数
注意事项
- 数据格式:确保
options数据包含valueKey和labelKey指定的字段 - 异步加载:使用
loadOptions时,options属性将被忽略 - 批量输入:输入的分隔符支持换行、逗号、分号、空格等
- 性能优化:大数据量时建议使用异步加载和分页功能
- 自定义映射:使用
customMapFunction时,需要确保返回正确的值数组
