diff --git a/components/select/index.tsx b/components/select/index.tsx
index c6a9f10fc..30c2a8bc7 100644
--- a/components/select/index.tsx
+++ b/components/select/index.tsx
@@ -1,12 +1,12 @@
-import { computed, defineComponent, inject, ref, VNodeChild, App, PropType, Plugin } from 'vue';
+import { computed, defineComponent, ref, VNodeChild, App, PropType, Plugin } from 'vue';
import omit from 'omit.js';
import classNames from '../_util/classNames';
import RcSelect, { Option, OptGroup, SelectProps as RcSelectProps, BaseProps } from '../vc-select';
import { OptionProps as OptionPropsType } from '../vc-select/Option';
-import { defaultConfigProvider } from '../config-provider';
import getIcons from './utils/iconUtil';
import PropTypes from '../_util/vue-types';
import { tuple } from '../_util/type';
+import useConfigInject from '../_util/hooks/useConfigInject';
type RawValue = string | number;
@@ -74,11 +74,10 @@ const Select = defineComponent({
props: SelectProps(),
SECRET_COMBOBOX_MODE_DO_NOT_USE: 'SECRET_COMBOBOX_MODE_DO_NOT_USE',
emits: ['change', 'update:value'],
- setup(props: any, { attrs, emit }) {
+ slots: ['notFoundContent', 'suffixIcon', 'itemIcon', 'removeIcon', 'clearIcon', 'dropdownRender'],
+ setup(props, { attrs, emit, slots, expose }) {
const selectRef = ref(null);
- const configProvider = inject('configProvider', defaultConfigProvider);
-
const focus = () => {
if (selectRef.value) {
selectRef.value.focus();
@@ -104,122 +103,100 @@ const Select = defineComponent({
return mode;
});
- const prefixCls = computed(() => {
- return configProvider.getPrefixCls('select', props.prefixCls);
- });
+ const { prefixCls, direction, configProvider } = useConfigInject('select', props);
const mergedClassName = computed(() =>
- classNames(
- {
- [`${prefixCls.value}-lg`]: props.size === 'large',
- [`${prefixCls.value}-sm`]: props.size === 'small',
- [`${prefixCls.value}-rtl`]: props.direction === 'rtl',
- [`${prefixCls.value}-borderless`]: !props.bordered,
- },
- attrs.class,
- ),
+ classNames({
+ [`${prefixCls.value}-lg`]: props.size === 'large',
+ [`${prefixCls.value}-sm`]: props.size === 'small',
+ [`${prefixCls.value}-rtl`]: direction.value === 'rtl',
+ [`${prefixCls.value}-borderless`]: !props.bordered,
+ }),
);
const triggerChange = (...args: any[]) => {
emit('update:value', args[0]);
emit('change', ...args);
};
- return {
- selectRef,
- mergedClassName,
- mode,
- focus,
+ expose({
blur,
- configProvider,
- triggerChange,
- prefixCls,
- };
- },
- render() {
- const {
- configProvider,
- mode,
- mergedClassName,
- triggerChange,
- prefixCls,
- $slots: slots,
- $props,
- } = this as any;
- const props: SelectTypes = $props;
- const {
- notFoundContent,
- listHeight = 256,
- listItemHeight = 24,
- getPopupContainer,
- dropdownClassName,
- direction,
- virtual,
- dropdownMatchSelectWidth,
- } = props;
-
- const { renderEmpty, getPopupContainer: getContextPopupContainer } = configProvider;
-
- const isMultiple = mode === 'multiple' || mode === 'tags';
-
- // ===================== Empty =====================
- let mergedNotFound: VNodeChild;
- if (notFoundContent !== undefined) {
- mergedNotFound = notFoundContent;
- } else if (slots.notFoundContent) {
- mergedNotFound = slots.notFoundContent();
- } else if (mode === 'combobox') {
- mergedNotFound = null;
- } else {
- mergedNotFound = renderEmpty('Select') as any;
- }
-
- // ===================== Icons =====================
- const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons(
- {
- ...this.$props,
- multiple: isMultiple,
- prefixCls,
- },
- slots,
- );
-
- const selectProps = omit(props, [
- 'prefixCls',
- 'suffixIcon',
- 'itemIcon',
- 'removeIcon',
- 'clearIcon',
- 'size',
- 'bordered',
- ]) as any;
-
- const rcSelectRtlDropDownClassName = classNames(dropdownClassName, {
- [`${prefixCls}-dropdown-${direction}`]: direction === 'rtl',
+ focus,
});
- return (
-
- {slots.default?.()}
-
- );
+ return () => {
+ const {
+ notFoundContent,
+ listHeight = 256,
+ listItemHeight = 24,
+ getPopupContainer,
+ dropdownClassName,
+ virtual,
+ dropdownMatchSelectWidth,
+ } = props;
+
+ const { renderEmpty, getPopupContainer: getContextPopupContainer } = configProvider;
+
+ const isMultiple = mode.value === 'multiple' || mode.value === 'tags';
+
+ // ===================== Empty =====================
+ let mergedNotFound: VNodeChild;
+ if (notFoundContent !== undefined) {
+ mergedNotFound = notFoundContent;
+ } else if (slots.notFoundContent) {
+ mergedNotFound = slots.notFoundContent();
+ } else if (mode.value === 'combobox') {
+ mergedNotFound = null;
+ } else {
+ mergedNotFound = renderEmpty('Select') as any;
+ }
+
+ // ===================== Icons =====================
+ const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons(
+ {
+ ...props,
+ multiple: isMultiple,
+ prefixCls: prefixCls.value,
+ },
+ slots,
+ );
+
+ const selectProps = omit(props, [
+ 'prefixCls',
+ 'suffixIcon',
+ 'itemIcon',
+ 'removeIcon',
+ 'clearIcon',
+ 'size',
+ 'bordered',
+ ]);
+
+ const rcSelectRtlDropDownClassName = classNames(dropdownClassName, {
+ [`${prefixCls.value}-dropdown-${direction.value}`]: direction.value === 'rtl',
+ });
+ return (
+
+ {slots.default?.()}
+
+ );
+ };
},
});
/* istanbul ignore next */