From f31d3b6d0ca992bb442c6a17c541172f8edb4fa9 Mon Sep 17 00:00:00 2001 From: Noki <1442045853@qq.com> Date: Tue, 11 Mar 2025 23:24:07 +0800 Subject: [PATCH] fix(components): [select] typed value causes `default-first-option` to fail (#19806) * fix(components): [select] default-first-option * fix(components): [select] watch optionArray ref * test(components): [select] add default-first-option * test(components): [select] remove only * test(components): [select] use remote-method * fix(components): [select] add condition for optionsArray loop * fix(components): [select] remove condition for optionsArray loop --- .../select/__tests__/select.test.ts | 64 +++++++++++++++++++ packages/components/select/src/useSelect.ts | 21 +++--- 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/packages/components/select/__tests__/select.test.ts b/packages/components/select/__tests__/select.test.ts index 3f9fe7c7c3..a43b077e80 100644 --- a/packages/components/select/__tests__/select.test.ts +++ b/packages/components/select/__tests__/select.test.ts @@ -2975,6 +2975,70 @@ describe('Select', () => { vi.useRealTimers() }) + + // fix: 11930 + it('should work when options changed', async () => { + vi.useFakeTimers() + + const wrapper = _mount( + ` + + + + `, + () => ({ + value: '', + options: [ + { + value: 'a', + label: 'a', + }, + ], + }), + { + methods: { + remoteMethod() { + setTimeout(() => { + this.options = [ + { + value: 0, + label: 0, + }, + ] + }, 200) + }, + }, + } + ) + + const select = wrapper.findComponent({ name: 'ElSelect' }) + const selectVm = select.vm as any + const input = wrapper.find('input') + input.element.focus() + + vi.runAllTimers() + await nextTick() + let options = getOptions() + expect(hasClass(options[0], 'is-hovering')).toBeTruthy() + + selectVm.onInput({ + target: { + value: '0', + }, + }) + + vi.runAllTimers() + await nextTick() + options = getOptions() + expect(hasClass(options[0], 'is-hovering')).toBeTruthy() + + vi.useRealTimers() + }) }) it('should keep the selected label after filtering options', async () => { diff --git a/packages/components/select/src/useSelect.ts b/packages/components/select/src/useSelect.ts index b0b74bf393..328445d795 100644 --- a/packages/components/select/src/useSelect.ts +++ b/packages/components/select/src/useSelect.ts @@ -406,19 +406,16 @@ export const useSelect: useSelectType = (props: ISelectProps, emit) => { } ) - watch( - () => states.hoveringIndex, - (val) => { - if (isNumber(val) && val > -1) { - hoverOption.value = optionsArray.value[val] || {} - } else { - hoverOption.value = {} - } - optionsArray.value.forEach((option) => { - option.hover = hoverOption.value === option - }) + watch([() => states.hoveringIndex, optionsArray], ([val]) => { + if (isNumber(val) && val > -1) { + hoverOption.value = optionsArray.value[val] || {} + } else { + hoverOption.value = {} } - ) + optionsArray.value.forEach((option) => { + option.hover = hoverOption.value === option + }) + }) watchEffect(() => { // Anything could cause options changed, then update options