diff --git a/components/select/optionList.tsx b/components/select/optionList.tsx index 067950da..5591e870 100644 --- a/components/select/optionList.tsx +++ b/components/select/optionList.tsx @@ -11,6 +11,7 @@ import VirtualList from '../virtual-list/virtualList'; import CheckOutlined from '../icon/CheckOutlined'; import { noop } from '../_util/utils'; import { useLocale } from '../config-provider/useLocale'; +import TextHightlight from '../text-highlight'; import { PADDING_LEFT_BASE, PADDING_LEFT_INDENT } from './const'; import { selectProps } from './props'; import type { SelectOption, SelectValue } from './interface'; @@ -46,6 +47,8 @@ const optionListProps = { renderOption: Function, renderEmpty: Function, hoverOptionValue: [String, Number, Object] as PropType, + filterText: String, + filterTextHighlight: Boolean, } as const satisfies ComponentObjectPropsOptions; export default defineComponent({ @@ -91,7 +94,14 @@ export default defineComponent({ return ( <> - {option.label} + {props.filterTextHighlight && props.filterText && !option.__cache + ? ( + + {option.label} + + ) + : option.label + } {option.__cache && ( - {t('select.tagOption')} @@ -164,7 +174,7 @@ export default defineComponent({ const renderDefault = ({ source }: { source: SelectOption }) => source.__isGroup ? renderGroupOption(source) : renderOption(source); - const inValidValueKey = '_ALL_KEY_' + const inValidValueKey = '_ALL_KEY_'; return () => enableVirtualScroll.value @@ -215,8 +225,8 @@ export default defineComponent({ : (
diff --git a/components/select/props.ts b/components/select/props.ts index d854faf8..0c1a8a07 100644 --- a/components/select/props.ts +++ b/components/select/props.ts @@ -51,6 +51,10 @@ export const selectProps = { (pattern: string, option: object) => boolean >, }, + filterTextHighlight: { + type: Boolean, + default: false, + }, collapseTags: { type: Boolean, default: false, diff --git a/components/select/select.vue b/components/select/select.vue index 46328ba8..17b63118 100644 --- a/components/select/select.vue +++ b/components/select/select.vue @@ -53,6 +53,8 @@ :renderOption="$slots.option" :renderEmpty="$slots.empty" :virtualScroll="virtualScroll" + :filterText="filterText" + :filterTextHighlight="filterTextHighlight" @scroll="onScroll" @mousedown.prevent /> @@ -95,7 +97,7 @@ export default defineComponent({ OptionList, }, props: selectProps, - emits: [UPDATE_MODEL_EVENT, CHANGE_EVENT, 'removeTag', 'visibleChange', 'focus', 'blur', 'clear', 'scroll', 'search'], + emits: [UPDATE_MODEL_EVENT, CHANGE_EVENT, 'removeTag', 'visibleChange', 'focus', 'blur', 'clear', 'scroll', 'search', 'filter'], setup(props, { emit }) { useTheme(); const { validate, isError, isFormDisabled } = useFormAdaptor({ @@ -316,6 +318,7 @@ export default defineComponent({ }, ) => { filterText.value = val; + emit('filter', val); // blur 自动清的 inputText 不触发 search if (props.remote && !extraInfo?.isClear) { emit('search', val); @@ -420,6 +423,7 @@ export default defineComponent({ onHover, onKeyDown, warnDeprecatedSlot, + filterText, }; }, }); diff --git a/docs/.vitepress/components/select/filterable.vue b/docs/.vitepress/components/select/filterable.vue index 409b3423..9b80a463 100644 --- a/docs/.vitepress/components/select/filterable.vue +++ b/docs/.vitepress/components/select/filterable.vue @@ -1,53 +1,130 @@ - diff --git a/docs/.vitepress/components/select/index.md b/docs/.vitepress/components/select/index.md index e9979246..34036835 100644 --- a/docs/.vitepress/components/select/index.md +++ b/docs/.vitepress/components/select/index.md @@ -136,31 +136,32 @@ selectGroupOption.vue ## Select Props -| 属性 | 说明 | 类型 | 默认值 | -|----------------------|----------------------------------------------------------|----------------------------------------------|-----------------------| -| appendToContainer | 弹窗内容是否添加到指定的 DOM 元素 | boolean | `true` | -| clearable | 是否显示清除按钮 | boolean | `false` | -| disabled | 是否禁用 | boolean | `false` | -| collapseTags | 多选时选中项是否折叠展示 | boolean | `false` | -| collapseTagsLimit | 多选时选中项超出限制个数后才会折叠 | number | 1 | +| 属性 | 说明 | 类型 | 默认值 | +| -------------------- | ------------------------------------------------------------- | -------------------------------------------- | --------------------- | +| appendToContainer | 弹窗内容是否添加到指定的 DOM 元素 | boolean | `true` | +| clearable | 是否显示清除按钮 | boolean | `false` | +| disabled | 是否禁用 | boolean | `false` | +| collapseTags | 多选时选中项是否折叠展示 | boolean | `false` | +| collapseTagsLimit | 多选时选中项超出限制个数后才会折叠 | number | 1 | | tagBordered | 多选时,选中项展示是否有边框(disabled 为 true 时强制有边框) | boolean | `false` | -| emptyText | 选项为空时显示的文字,也可以使用#empty 设置 | string | `无数据` | -| getContainer | 指定下拉选项挂载的 HTML 节点 | () => HTMLElement | `() => document.body` | -| multiple | 是否多选 | boolean | `false` | -| multipleLimit | 多选时用户最多可以选择的项目数,为 0 则不限制 | number | `0` | -| placeholder | 当没有选择内容时的提示语 | string | - | -| modelValue / v-model | 选中的值 | number / string / boolean / object | - | -| filterable | 是否支持过滤选项 | boolean | `false` | -| filter | 自定义过滤函数 | (pattern: string, option: object) => boolean | `-` | -| tag | 是否可以创建新的选项,需要和 `filterable` 一起使用 | boolean | `false` | -| remote | 是否远程搜索,当输入内容时触发`search`事件 | boolean | `false` | -| options | 选项配置 | array\ | `[]` | -| virtualScroll | 虚拟滚动 | boolean / number | `true` | -| valueField | 替代 `SelectOption` 中的 `value` 字段名 | string | `value` | -| labelField | 替代 `SelectOption` 中的 `label` 字段名 | string | `label` | -| popperClass | 弹出框容器样式 | string | - | -| triggerClass | 弹出框触发器样式类 | string | - | -| triggerStyle | 弹出框触发器样式 | string / object | - | +| emptyText | 选项为空时显示的文字,也可以使用#empty 设置 | string | `无数据` | +| getContainer | 指定下拉选项挂载的 HTML 节点 | () => HTMLElement | `() => document.body` | +| multiple | 是否多选 | boolean | `false` | +| multipleLimit | 多选时用户最多可以选择的项目数,为 0 则不限制 | number | `0` | +| placeholder | 当没有选择内容时的提示语 | string | - | +| modelValue / v-model | 选中的值 | number / string / boolean / object | - | +| filterable | 是否支持过滤选项 | boolean | `false` | +| filter | 自定义过滤函数 | (pattern: string, option: object) => boolean | `-` | +| filterTextHighlight | 过滤文本是否高亮 | boolean | `false` | +| tag | 是否可以创建新的选项,需要和 `filterable` 一起使用 | boolean | `false` | +| remote | 是否远程搜索,当输入内容时触发`search`事件 | boolean | `false` | +| options | 选项配置 | array\ | `[]` | +| virtualScroll | 虚拟滚动 | boolean / number | `true` | +| valueField | 替代 `SelectOption` 中的 `value` 字段名 | string | `value` | +| labelField | 替代 `SelectOption` 中的 `label` 字段名 | string | `label` | +| popperClass | 弹出框容器样式 | string | - | +| triggerClass | 弹出框触发器样式类 | string | - | +| triggerStyle | 弹出框触发器样式 | string / object | - | ## Select Events @@ -174,17 +175,18 @@ selectGroupOption.vue | clear | 点击清除按钮时触发 | (event: Event) | | scroll | 滚动事件 | (event: Event) | | search | 搜索事件 | ( query: String) | +| filter | 过滤事件 | ( query: String) | ## Select Slots -| 名称 | 说明 | 参数 | -|---------|---------------------------------------------|----------------------------------------------------| -| default | option 和 selectGroupOption 组件列表 | - | -| empty | 无选项的内容 | - | -| option | 自定义 `Option` 内容 | _{ value, label, disabled, isSelected }_ | +| 名称 | 说明 | 参数 | +| ------- | ---------------------------------------------- | -------------------------------------------------- | +| default | option 和 selectGroupOption 组件列表 | - | +| empty | 无选项的内容 | - | +| option | 自定义 `Option` 内容 | _{ value, label, disabled, isSelected }_ | | tag | 控制标签的渲染,自定义选中选项在选择框如何展示 | _{ option: SelectOption, handleClose: ()=> void }_ | -| header | 弹框顶部显示自定义的内容 | - | -| footer | 弹框底部显示自定义的内容 | - | +| header | 弹框顶部显示自定义的内容 | - | +| footer | 弹框底部显示自定义的内容 | - | | addon | 即将废弃,请使用 footer | - | ## Select Methods @@ -217,9 +219,9 @@ selectGroupOption.vue ## SelectOption -| 属性 | 说明 | 类型 | -| -------- | ------------------------------------ | ---------------------------------- | -| value | 非分组选项的值,需要唯一 | string / number / boolean / object | -| label | 选项的标签 | string / number | -| disabled | 是否禁用 | boolean | +| 属性 | 说明 | 类型 | +| -------- | -------------------------------- | ---------------------------------- | +| value | 非分组选项的值,需要唯一 | string / number / boolean / object | +| label | 选项的标签 | string / number | +| disabled | 是否禁用 | boolean | | children | 若为数组类型,则当前项为分组选项 | `Array` |