From 20b574700b30b040e290a4bcabec36d2b2ece03f Mon Sep 17 00:00:00 2001 From: bchen1029 <39672197+bchen1029@users.noreply.github.com> Date: Fri, 1 Oct 2021 02:30:31 +0800 Subject: [PATCH] fix(components): fix composition event bug (#3659) --- .../cascader/__tests__/cascader.spec.ts | 7 +++++- packages/components/cascader/src/index.vue | 25 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/components/cascader/__tests__/cascader.spec.ts b/packages/components/cascader/__tests__/cascader.spec.ts index b64b856d8c..5cc0d4ee34 100644 --- a/packages/components/cascader/__tests__/cascader.spec.ts +++ b/packages/components/cascader/__tests__/cascader.spec.ts @@ -257,8 +257,13 @@ describe('Cascader.vue', () => { const input = wrapper.find('input') const dropdown = document.querySelector(DROPDOWN) - input.element.value = 'Ha' + input.element.value = 'Ni' + await input.trigger('compositionstart') await input.trigger('input') + input.element.value = 'Ha' + await input.trigger('compositionupdate') + await input.trigger('input') + await input.trigger('compositionend') const suggestions = dropdown.querySelectorAll( SUGGESTION_ITEM ) as NodeListOf diff --git a/packages/components/cascader/src/index.vue b/packages/components/cascader/src/index.vue index efafe81c61..2a9c8833d7 100644 --- a/packages/components/cascader/src/index.vue +++ b/packages/components/cascader/src/index.vue @@ -37,6 +37,9 @@ :validate-event="false" :size="realSize" :class="{ 'is-focus': popperVisible }" + @compositionstart="handleComposition" + @compositionupdate="handleComposition" + @compositionend="handleComposition" @focus="(e) => $emit('focus', e)" @blur="(e) => $emit('blur', e)" @input="handleInput" @@ -83,6 +86,9 @@ @input="(e) => handleInput(searchInputValue, e)" @click.stop="togglePopperVisible(true)" @keydown.delete="handleDelete" + @compositionstart="handleComposition" + @compositionupdate="handleComposition" + @compositionend="handleComposition" /> @@ -168,6 +174,7 @@ import { removeResizeListener, } from '@element-plus/utils/resize-event' import { isValidComponentSize } from '@element-plus/utils/validators' +import { isKorean } from '@element-plus/utils/isDef' import type { Options } from '@element-plus/components/popper' import type { ComputedRef, PropType, Ref } from 'vue' @@ -295,6 +302,7 @@ export default defineComponent({ const searchInputValue = ref('') const presentTags: Ref = ref([]) const suggestions: Ref = ref([]) + const isOnComposition = ref(false) const isDisabled = computed(() => props.disabled || elForm.disabled) const inputPlaceholder = computed( @@ -500,7 +508,20 @@ export default defineComponent({ emit('expand-change', value) } + const handleComposition = (event: CompositionEvent) => { + const text = (event.target as HTMLInputElement)?.value + if (event.type === 'compositionend') { + isOnComposition.value = false + nextTick(() => handleInput(text)) + } else { + const lastCharacter = text[text.length - 1] || '' + isOnComposition.value = !isKorean(lastCharacter) + } + } + const handleKeyDown = (e: KeyboardEvent) => { + if (isOnComposition.value) return + switch (e.code) { case EVENT_CODE.enter: togglePopperVisible() @@ -565,7 +586,7 @@ export default defineComponent({ } }, props.debounce) - const handleInput = (val: string, e: KeyboardEvent) => { + const handleInput = (val: string, e?: KeyboardEvent) => { !popperVisible.value && togglePopperVisible(true) if (e?.isComposing) return @@ -614,6 +635,7 @@ export default defineComponent({ presentTags, suggestions, isDisabled, + isOnComposition, realSize, tagSize, multiple, @@ -627,6 +649,7 @@ export default defineComponent({ getCheckedNodes, handleExpandChange, handleKeyDown, + handleComposition, handleClear, handleSuggestionClick, handleDelete,