# BySelect 选择器组件
基于 Element UI Select 的高级选择器组件,提供数据选择、远程搜索、异步加载、分组选项等功能。
注意:本组件基于 Element UI Select 实现,支持 Element UI Select 的所有功能。如需了解更多高级配置和功能,请参考 Element UI Select 官方文档 (opens new window)。
# 基础用法
<template>
<by-select v-model="value" :options="options" :config="config" placeholder="请选择" />
</template>
<script>
export default {
data() {
return {
value: '',
options: [
{ label: '选项1', value: 'option1' },
{ label: '选项2', value: 'option2' },
{ label: '选项3', value: 'option3' }
],
config: {
placeholder: '请选择',
optionLabel: 'label',
optionValue: 'value'
}
}
}
}
</script>
# 高级功能
# 1. 多选模式
支持多选模式,可以选择多个选项。
<template>
<by-select v-model="multiValue" :options="options" multiple placeholder="请选择多个选项" />
</template>
<script>
export default {
data() {
return {
multiValue: [],
options: [
{ label: '选项一', value: 'option1' },
{ label: '选项二', value: 'option2' },
{ label: '选项三', value: 'option3' },
{ label: '选项四', value: 'option4' }
]
}
}
}
</script>
特性:
- 支持选择多个选项
- 自动处理多选数据格式
- 支持标签移除功能
- 解决多选时选择后下拉数据重置问题
# 2. 远程搜索
支持远程搜索数据,适用于大数据量场景。
<template>
<by-select
v-model="remoteValue"
:options="remoteOptions"
:remote="true"
:loading="loading"
@search="handleRemoteSearch"
placeholder="请输入关键字搜索"
/>
</template>
<script>
export default {
data() {
return {
remoteValue: '',
remoteOptions: [],
loading: false
}
},
methods: {
async handleRemoteSearch(query) {
if (query) {
this.loading = true
try {
// 模拟远程搜索
const { data } = await this.$http.get('/api/search', {
params: { keyword: query }
})
this.remoteOptions = data.map(item => ({
label: item.name,
value: item.id
}))
} catch (error) {
console.error(error)
} finally {
this.loading = false
}
} else {
this.remoteOptions = []
}
}
}
}
</script>
特性:
- 支持远程数据搜索
- 自动处理加载状态
- 支持搜索防抖
- 优化用户体验
# 3. 异步加载选项
支持异步加载选项数据,适用于动态数据场景。
<template>
<by-select v-model="asyncValue" :load-options="loadOptions" :auto-load="true" :config="config" placeholder="请选择" />
</template>
<script>
export default {
data() {
return {
asyncValue: '',
config: {
optionLabel: 'name',
optionValue: 'id'
}
}
},
methods: {
async loadOptions() {
// 模拟异步加载数据
const { data } = await this.$http.get('/api/options')
return data
}
}
}
</script>
特性:
- 支持组件挂载时自动加载
- 支持手动刷新数据
- 支持展开时重新加载
- 自动处理加载状态
# 4. 分组选项
支持选项分组显示,适用于分类数据展示。
<template>
<by-select v-model="groupValue" :options="groupOptions" :config="groupConfig" placeholder="请选择" />
</template>
<script>
export default {
data() {
return {
groupValue: '',
groupOptions: [
{
label: '热门城市',
options: [
{ label: '北京', value: 'beijing' },
{ label: '上海', value: 'shanghai' }
]
},
{
label: '其他城市',
options: [
{ label: '深圳', value: 'shenzhen' },
{ label: '广州', value: 'guangzhou' }
]
}
],
groupConfig: {
mode: 'group',
optionLabel: 'label',
optionValue: 'value'
}
}
}
}
</script>
特性:
- 支持多级分组显示
- 灵活的分组数据结构
- 保持所有选择功能
- 支持分组标签自定义
# 5. 可清空选择
支持清空已选择的选项。
<template>
<by-select v-model="clearableValue" :options="options" clearable placeholder="请选择(可清空)" />
</template>
<script>
export default {
data() {
return {
clearableValue: '',
options: [
{ label: '选项1', value: 'option1' },
{ label: '选项2', value: 'option2' }
]
}
}
}
</script>
特性:
- 支持清空已选择的值
- 提供清空按钮
- 触发清空事件
- 提升用户体验
# 6. 禁用状态
支持禁用选择器,适用于权限控制场景。
<template>
<by-select v-model="disabledValue" :options="options" :disabled="true" placeholder="禁用状态" />
</template>
<script>
export default {
data() {
return {
disabledValue: '',
options: [
{ label: '选项1', value: 'option1' },
{ label: '选项2', value: 'option2' }
]
}
}
}
</script>
特性:
- 支持整体禁用
- 适用于权限控制
- 防止用户误操作
- 清晰的视觉反馈
# 7. 自定义配置
支持灵活的数据字段配置,适配不同的数据结构。
<template>
<by-select v-model="customValue" :options="customOptions" :config="customConfig" placeholder="请选择" />
</template>
<script>
export default {
data() {
return {
customValue: '',
customOptions: [
{ name: '用户1', id: 1 },
{ name: '用户2', id: 2 }
],
customConfig: {
optionLabel: 'name', // 自定义标签字段
optionValue: 'id', // 自定义值字段
placeholder: '请选择用户'
}
}
}
}
</script>
特性:
- 支持自定义字段映射
- 适配不同数据结构
- 灵活的配置选项
- 提升组件复用性
# API
# Props
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
value | 绑定值 | String/Number/Array | '' |
options | 选项数据 | Array | [] |
config | 配置对象 | Object | {} |
placeholder | 占位符 | String | 请选择 |
loadOptions | 异步加载选项函数 | Function | null |
autoLoad | 是否自动加载 | Boolean | true |
multiple | 是否多选 | Boolean | false |
remote | 是否远程搜索 | Boolean | false |
clearable | 是否可清空 | Boolean | false |
disabled | 是否禁用 | Boolean | false |
loading | 是否加载中 | Boolean | false |
# Config 配置项
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
placeholder | 占位符文本 | String | 请选择 |
optionLabel | 选项标签字段 | String | label |
optionValue | 选项值字段 | String | value |
mode | 模式类型 | String | - |
refreshOnOpen | 展开时是否刷新 | Boolean | false |
# Events
事件名 | 说明 | 参数 |
---|---|---|
change | 选中值发生变化时触发 | 选中的值 |
visible-change | 下拉框出现/隐藏时触发 | 出现则为true |
remove-tag | 多选模式下移除tag时触发 | 移除的tag值 |
clear | 可清空的单选模式下用户点击清空按钮时触发 | — |
blur | 当input失去焦点时触发 | (event: Event) |
focus | 当input获得焦点时触发 | (event: Event) |
search | 远程搜索时触发 | 搜索关键字 |
load-success | 异步加载成功时触发 | 加载的数据 |
load-error | 异步加载失败时触发 | 错误信息 |
# Methods
方法名 | 说明 | 参数 |
---|---|---|
refresh | 手动刷新数据 | - |
# 选项配置
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
label | 选项的标签,若不设置则默认与 value 相同 | string/number | — |
value | 选项的值 | string/number/object | — |
disabled | 是否禁用该选项 | boolean | false |
options | 分组时,该分组下的选项(分组模式时使用) | array | — |
# 完整示例
# 结合表单使用的完整示例
<template>
<div>
<el-form :model="form" label-width="100px">
<el-form-item label="用户类型">
<by-select v-model="form.userType" :options="userTypeOptions" placeholder="请选择用户类型" />
</el-form-item>
<el-form-item label="用户列表">
<by-select
v-model="form.users"
:load-options="loadUserOptions"
:config="userConfig"
multiple
placeholder="请选择用户"
/>
</el-form-item>
<el-form-item label="城市">
<by-select v-model="form.city" :options="cityOptions" :config="cityConfig" clearable placeholder="请选择城市" />
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
form: {
userType: '',
users: [],
city: ''
},
userTypeOptions: [
{ label: '管理员', value: 'admin' },
{ label: '普通用户', value: 'user' },
{ label: '访客', value: 'guest' }
],
userConfig: {
optionLabel: 'name',
optionValue: 'id'
},
cityOptions: [
{
label: '一线城市',
options: [
{ label: '北京', value: 'beijing' },
{ label: '上海', value: 'shanghai' }
]
},
{
label: '二线城市',
options: [
{ label: '杭州', value: 'hangzhou' },
{ label: '南京', value: 'nanjing' }
]
}
],
cityConfig: {
mode: 'group',
optionLabel: 'label',
optionValue: 'value'
}
}
},
methods: {
async loadUserOptions() {
// 模拟异步加载用户数据
const { data } = await this.$http.get('/api/users')
return data
}
}
}
</script>
# 远程搜索示例
<template>
<div>
<by-select
v-model="searchValue"
:options="searchOptions"
:remote="true"
:loading="searchLoading"
:config="searchConfig"
filterable
@search="handleSearch"
placeholder="请输入关键字搜索"
/>
</div>
</template>
<script>
export default {
data() {
return {
searchValue: '',
searchOptions: [],
searchLoading: false,
searchConfig: {
optionLabel: 'title',
optionValue: 'id'
}
}
},
methods: {
async handleSearch(query) {
if (query) {
this.searchLoading = true
try {
const { data } = await this.$http.get('/api/search', {
params: { keyword: query }
})
this.searchOptions = data
} catch (error) {
console.error('搜索失败:', error)
} finally {
this.searchLoading = false
}
} else {
this.searchOptions = []
}
}
}
}
</script>
# 样式类
类名 | 说明 |
---|---|
.by-select | 选择器组件根容器 |
.by-select--disabled | 禁用状态样式 |
.by-select--loading | 加载状态样式 |
.by-select--multiple | 多选模式样式 |
# 注意事项
- 数据格式:确保
options
数据格式正确,包含必要的label
和value
字段 - 异步加载:使用
loadOptions
时,确保函数返回正确的数据格式 - 远程搜索:启用远程搜索时,需要正确处理搜索逻辑和加载状态
- 分组模式:使用分组模式时,需要设置
config.mode = 'group'
- 字段映射:通过
config.optionLabel
和config.optionValue
自定义字段映射 - 多选处理:多选模式下,确保正确处理数组类型的数据
- 性能优化:大数据量时建议使用远程搜索或异步加载
- 事件处理:正确处理各种事件,特别是异步操作的成功和失败回调