diff --git a/components/vc-select/BaseSelect.tsx b/components/vc-select/BaseSelect.tsx index 72f50d8405..7765e8d4cf 100644 --- a/components/vc-select/BaseSelect.tsx +++ b/components/vc-select/BaseSelect.tsx @@ -281,6 +281,14 @@ export default defineComponent({ const selectorRef = shallowRef(null); const listRef = shallowRef(null); const blurRef = ref(false); + const compositionStatus = ref(false); // 基于BaseSelect定义当前是否处于输入法组合状态 + const onCompositionStart = () => { + // 输入法组合开始时,设置compositionStatus为true + compositionStatus.value = true; + }; + const onCompositionEnd = () => { + compositionStatus.value = false; + }; /** Used for component focused management */ const [mockFocused, setMockFocused, cancelSetMockFocused] = useDelayReset(); @@ -765,6 +773,7 @@ export default defineComponent({ let clearNode: VueNode; const onClearMouseDown: MouseEventHandler = () => { onClear?.(); + onCompositionEnd(); onDisplayValuesChange([], { type: 'clear', @@ -866,6 +875,9 @@ export default defineComponent({ onSearchSubmit={onInternalSearchSubmit} onRemove={onSelectorRemove} tokenWithEnter={tokenWithEnter.value} + compositionStatus={compositionStatus.value} + onCompositionStart={onCompositionStart} + onCompositionEnd={onCompositionEnd} /> ); }, diff --git a/components/vc-select/Selector/SingleSelector.tsx b/components/vc-select/Selector/SingleSelector.tsx index 58aba8cb5d..5abcad3475 100644 --- a/components/vc-select/Selector/SingleSelector.tsx +++ b/components/vc-select/Selector/SingleSelector.tsx @@ -44,6 +44,9 @@ const SingleSelector = defineComponent({ setup(props) { const inputChanged = shallowRef(false); + // 本地输入状态管理 + const hasInput = shallowRef(false); + const combobox = computed(() => props.mode === 'combobox'); const inputEditable = computed(() => combobox.value || props.showSearch); @@ -65,12 +68,38 @@ const SingleSelector = defineComponent({ { immediate: true }, ); + // 监听下拉框关闭(失焦)时重置输入状态 + watch( + () => props.open, + newOpen => { + if (!newOpen) { + hasInput.value = false; + } + }, + ); + + // 监听选择完成(values变化)时重置输入状态 + watch( + () => props.values, + () => { + if (props.values && props.values.length > 0) { + hasInput.value = false; + } + }, + { deep: true }, + ); + // Not show text when closed expect combobox mode - const hasTextInput = computed(() => - props.mode !== 'combobox' && !props.open && !props.showSearch + const hasTextInput = computed(() => { + // 只有在本地输入状态为true时,才认为有文本输入 + if (!hasInput.value) { + return false; + } + + return props.mode !== 'combobox' && !props.open && !props.showSearch ? false - : !!inputValue.value || props.compositionStatus, - ); + : !!inputValue.value || props.compositionStatus; + }); const title = computed(() => { const item = props.values[0]; @@ -92,6 +121,10 @@ const SingleSelector = defineComponent({ }; const handleInput = (e: Event) => { const composing = (e.target as any).composing; + + // 用户输入时设置输入状态为true + hasInput.value = true; + if (!composing) { inputChanged.value = true; props.onInputChange(e); diff --git a/components/vc-select/Selector/index.tsx b/components/vc-select/Selector/index.tsx index ccc121b089..530f69c4f8 100644 --- a/components/vc-select/Selector/index.tsx +++ b/components/vc-select/Selector/index.tsx @@ -15,7 +15,7 @@ import type { CustomTagProps, DisplayValueType, Mode, RenderNode } from '../Base import { isValidateOpenKey } from '../utils/keyUtil'; import useLock from '../hooks/useLock'; import type { PropType } from 'vue'; -import { defineComponent, ref } from 'vue'; +import { defineComponent, ref, computed } from 'vue'; import createRef from '../../_util/createRef'; import PropTypes from '../../_util/vue-types'; import type { VueNode } from '../../_util/type'; @@ -60,6 +60,9 @@ export interface SelectorProps { onSearchSubmit: (searchText: string) => void; onRemove: (value: DisplayValueType) => void; onInputKeyDown?: (e: KeyboardEvent) => void; + compositionStatus?: boolean; + onCompositionStart?: () => void; + onCompositionEnd?: () => void; /** * @private get real dom for trigger align. @@ -115,6 +118,9 @@ const Selector = defineComponent({ onSearchSubmit: Function, onRemove: Function, onInputKeyDown: { type: Function as PropType }, + compositionStatus: { type: Boolean, default: false }, + onCompositionStart: { type: Function as PropType<() => void> }, + onCompositionEnd: { type: Function as PropType<() => void> }, /** * @private get real dom for trigger align. @@ -124,7 +130,7 @@ const Selector = defineComponent({ } as any, setup(props, { expose }) { const inputRef = createRef(); - const compositionStatus = ref(false); + const compositionStatus = computed(() => props.compositionStatus || false); // ====================== Input ====================== const [getInputMouseDown, setInputMouseDown] = useLock(0); @@ -174,11 +180,13 @@ const Selector = defineComponent({ }; const onInputCompositionStart = () => { - compositionStatus.value = true; + // compositionStatus.value = true; + props.onCompositionStart(); }; const onInputCompositionEnd = (e: InputEvent) => { - compositionStatus.value = false; + // compositionStatus.value = false; + props.onCompositionEnd(); // Trigger search again to support `tokenSeparators` with typewriting if (props.mode !== 'combobox') { triggerOnSearch((e.target as HTMLInputElement).value); @@ -244,6 +252,8 @@ const Selector = defineComponent({ inputRef.current.focus(); }, blur: () => { + console.log('onBlurrrrrrrr1111111'); + props.onCompositionEnd(); inputRef.current.blur(); }, });