SelectGroup 分组选择器
下拉分组选择器。
代码演示
基本用法
基本用法。
<template>
<div class="box">
<p>单选</p>
{{ value1 }}
<f-select-group
v-model:value="value1"
:options="options"
style="width: 200px"
placeholder="请选择"
allow-clear
/>
</div>
<div class="box">
<p>多选</p>
{{ value2 }}
<f-select-group
v-model:value="value2"
maxTagCount="responsive"
mode="multiple"
:options="options"
style="width: 200px"
placeholder="请选择"
allow-clear
showMaxTagPlaceholder
/>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
const createOptions = (start = 0, end = 6, level = 2, key = '', childrenValue: any = undefined) => {
level--
const list: any[] = []
for (let i = start; i < end; i++) {
const value = key ? `${key}-${i}` : i + ''
list.push({
label: `选项${value}`,
value,
disabled: i === 2,
options: level ? createOptions(start, end, level, value) : childrenValue,
})
}
return list
}
export default defineComponent({
setup() {
const value1 = ref('1-1')
const value2 = ref(['1-1', '1-2'])
const options = ref<any[]>([])
setTimeout(() => {
options.value = createOptions(1, 10, 2, '')
}, 1500)
return {
value1,
value2,
options,
}
},
})
</script>
静态搜索
对options内选项进行搜索
<template>
<div class="box">
<p>单选</p>
{{ value1 }}
<f-select-group
v-model:value="value1"
:options="options"
style="width: 200px"
placeholder="请选择"
allow-clear
showSearch
/>
</div>
<div class="box">
<p>多选</p>
{{ value2 }}
<f-select-group
v-model:value="value2"
maxTagCount="responsive"
mode="multiple"
:options="options"
style="width: 200px"
placeholder="请选择"
allow-clear
showSearch
showMaxTagPlaceholder
/>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
const createOptions = (start = 0, end = 6, level = 2, key = '', childrenValue: any = undefined) => {
level--
const list: any[] = []
for (let i = start; i < end; i++) {
const value = key ? `${key}-${i}` : i + ''
list.push({
label: `选项${value}`,
value,
disabled: i === 2,
options: level ? createOptions(start, end, level, value) : childrenValue,
})
}
return list
}
export default defineComponent({
setup() {
const value1 = ref('1-1')
const value2 = ref(['1-1', '1-2'])
const options = ref<any[]>([])
setTimeout(() => {
options.value = createOptions(1, 10, 2, '')
}, 1500)
return {
value1,
value2,
options,
}
},
})
</script>
选项搜索
对一级选项进行搜索
<template>
<div class="box">
<p>数据loadData:{{ data.value }}</p>
<f-select-group
v-model:value="data.value"
maxTagCount="responsive"
mode="multiple"
:showSearch="true"
:options="data.options"
:loadData="loadData"
@search="onSearch"
style="width: 200px"
placeholder="请选择"
allow-clear
showMaxTagPlaceholder
>
<template #load-more="{ groupValue }">
<div v-if="!groupValue">
<span v-if="data.isLoading">加载中~</span>
<span v-if="data.isError">加载失败</span>
<span v-if="data.isFinish">已加载全部</span>
</div>
</template>
</f-select-group>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from 'vue'
const createOptions = (start = 0, end = 6, level = 2, key = '', childrenValue: any = undefined) => {
level--
const list: any[] = []
for (let i = start; i < end; i++) {
const value = key ? `${key}-${i}` : i + ''
list.push({
label: `选项${value}`,
value,
disabled: i === 2,
options: level ? createOptions(start, end, level, value) : childrenValue,
})
}
return list
}
export default defineComponent({
setup() {
const data = reactive({
value: null,
page: 1,
limt: 10,
searchValue: '',
options: [] as any[],
isLoading: false,
isError: false,
isFinish: false,
clear: null as any,
})
const onSearch = val => {
clearTimeout(data.clear)
data.page = 1
data.searchValue = val
data.isError = false
data.isLoading = false
data.isFinish = false
data.options = []
loadData(null)
}
const loadData = async groupValue => {
if (groupValue) return
if (data.isLoading || data.isFinish) return
return new Promise(resolve => {
data.isLoading = true
data.clear = setTimeout(() => {
if (!groupValue) {
const start = (data.page - 1) * data.limt
const end = start + 10
data.options = [...data.options, ...createOptions(start, end, 1, data.searchValue)]
data.page++
data.isLoading = false
if (data.options.length >= 50) {
data.isFinish = true
}
}
}, 1500)
})
}
return {
data,
onSearch,
loadData,
}
},
})
</script>```
对二级选项进行搜索
<template>
<div class="box">
<p>数据分组loadData:{{ data.value }}</p>
<f-select-group
v-model:value="data.value"
maxTagCount="responsive"
mode="multiple"
:showSearch="true"
:options="data.options"
:loadData="loadData"
@search="onSearch"
style="width: 200px"
placeholder="请选择"
allow-clear
:defaultValueOptions="[{ label: '选项1-1', value: '1-1' }]"
showMaxTagPlaceholder
>
<template #load-more="{ groupValue }">
<div v-if="groupValue">
<span v-if="data.isLoading">加载中~</span>
<span v-if="data.isError">加载失败</span>
<span v-if="data.isFinish">已加载全部</span>
</div>
</template>
</f-select-group>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from 'vue'
const createOptions = (start = 0, end = 6, level = 2, key = '', childrenValue: any = undefined) => {
level--
const list: any[] = []
for (let i = start; i < end; i++) {
const value = key ? `${key}-${i}` : i + ''
list.push({
label: `选项${value}`,
value,
disabled: i === 2,
options: level ? createOptions(start, end, level, value) : childrenValue,
})
}
return list
}
export default defineComponent({
setup() {
const data = reactive({
value: ['1-1'],
page: 1,
limt: 10,
searchValue: '',
options: createOptions(1, 10, 1, '', []) as any[],
isLoading: false,
isError: false,
isFinish: false,
groupValue: null,
clear: null as any,
})
const onSearch = val => {
clearTimeout(data.clear)
data.page = 1
data.searchValue = val
data.isError = false
data.isLoading = false
data.isFinish = false
const idx = data.options.findIndex(item => item.value === data.groupValue)
data.options[idx].options = []
loadData(data.groupValue)
}
const loadData = async groupValue => {
if (!groupValue) return
const newIdx = data.options.findIndex(item => item.value === groupValue)
const oldIdx = data.options.findIndex(item => item.value === data.groupValue)
if (data.groupValue !== groupValue && oldIdx !== -1) {
clearTimeout(data.clear)
data.options[oldIdx].options = []
data.page = 1
data.isError = false
data.isLoading = false
data.isFinish = false
}
data.groupValue = groupValue
if (data.isLoading || data.isFinish) return
return new Promise(resolve => {
data.isLoading = true
data.clear = setTimeout(() => {
const start = (data.page - 1) * data.limt
const end = start + 10
data.options[newIdx].options = [
...data.options[newIdx].options,
...createOptions(start, end, 1, data.searchValue + groupValue),
]
data.page++
data.isLoading = false
if (data.options[newIdx].options.length >= 30) {
data.isFinish = true
}
}, 1500)
})
}
return {
data,
onSearch,
loadData,
}
},
})
</script>
API
Select props
参数 | 说明 | 类型 | 默认值 | 版本 |
---|
pressLine | 组件右上角文本 | string | | |
showMaxTagPlaceholder | 多选情况下,是否展示超出内容文案 | boolean | false | |
tooltips | Tooltip文字提示组件展示文本,组件参数说明参考Tooltip文字提示组件,新增两个属性 textColor ,contentHeight | textColor:string contentHeight:number | | |
allowClear | 支持清除 | boolean | false | |
defaultValueOptions | 是否默认值的选项,解决在loaData模式下初始赋值数据不能回显 | array<{value, label, [disabled, key, title]}> | [] | |
disabled | 是否禁用 | boolean | false | |
fieldNames | 自定义节点 label、value、options 的字段 | object | { label: label , value: value , options: options } | 3.0 |
getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | function(triggerNode) | () => document.body | |
mode | 设置 Select 的模式为多选或标签 | multiple | single | single | |
options | options 数据,如果设置则不需要手动构造 selectOption 节点 | array<{value, label, [disabled, key, title]}> | [] | |
placeholder | 选择框默认文字 | string|slot | - | |
showArrow | 是否显示下拉小箭头 | boolean | 单选为true,多选为false | |
showSearch | 配置是否可搜索 | boolean|{filter, limit} | 单选为false,多选为true | |
size | 选择框大小,可选 large small | string | default | |
value(v-model) | 指定当前选中的条目 | string|string[]|number|number[] | - | |
事件
事件名称 | 说明 | 回调参数 |
---|
change | 选中 option,或 input 的 value 变化(combobox 模式下)时,调用此函数 | function(value, option:Option/Array<Option>) |
search | 文本框值变化时回调 | function(value: string) |
插槽
插槽名称 | 说明 | 参数 |
---|
load-more | <slot name="load-more" :group-value="groupValue" /> | groupValue为一级分组的value值,如果load-more对应的是一级分组内插槽则groupValue没有值 |
option | <slot name="option" type="option" :option="option" /> | type有group、option两种类型group表示一级分组option表示二级选项,option表示当前选项的传入的数据 |
提示
该组件是基于Select组件封装的,所以如果内容逻辑没干扰Select组件的属性、事件、插槽等都可以使用。