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:stringcontentHeight: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 | 选择框大小,可选 largesmall | 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组件的属性、事件、插槽等都可以使用。