diff --git a/packages/components/select/__tests__/select.test.ts b/packages/components/select/__tests__/select.test.ts index 22931a08ea..8d0d6a651a 100644 --- a/packages/components/select/__tests__/select.test.ts +++ b/packages/components/select/__tests__/select.test.ts @@ -2803,4 +2803,132 @@ describe('Select', () => { .display ).toBe('none') }) + + describe('check default first option after input', () => { + it('defalut', async () => { + vi.useFakeTimers() + wrapper = getSelectVm({ + filterable: true, + defaultFirstOption: true, + }) + + const select = wrapper.findComponent({ name: 'ElSelect' }) + const selectVm = select.vm as any + const input = wrapper.find('input') + input.element.focus() + + selectVm.onInput({ + target: { + value: '蚵仔煎', + }, + }) + + vi.runAllTimers() + await nextTick() + expect(selectVm.states.hoveringIndex).toBe(2) + + vi.useRealTimers() + }) + + it('with multiple', async () => { + vi.useFakeTimers() + wrapper = getSelectVm({ + multiple: true, + filterable: true, + defaultFirstOption: true, + }) + + const select = wrapper.findComponent({ name: 'ElSelect' }) + const selectVm = select.vm as any + const input = wrapper.find('input') + input.element.focus() + + selectVm.onInput({ + target: { + value: '蚵仔煎', + }, + }) + + vi.runAllTimers() + await nextTick() + expect(selectVm.states.hoveringIndex).toBe(2) + + vi.useRealTimers() + }) + + it('the value is string with value-key', async () => { + vi.useFakeTimers() + wrapper = getSelectVm({ + filterable: true, + defaultFirstOption: true, + valueKey: 'label', + }) + + const select = wrapper.findComponent({ name: 'ElSelect' }) + const selectVm = select.vm as any + const input = wrapper.find('input') + input.element.focus() + + selectVm.onInput({ + target: { + value: '蚵仔煎', + }, + }) + + vi.runAllTimers() + await nextTick() + expect(selectVm.states.hoveringIndex).toBe(2) + + vi.useRealTimers() + }) + + it('the value is object with value-key', async () => { + vi.useFakeTimers() + wrapper = _mount( + ` + + + + + `, + () => ({ + options: [ + { + id: 1, + name: '黄金糕', + }, + { + id: 2, + name: '双皮奶', + }, + { + id: 3, + name: '蚵仔煎', + }, + ], + }) + ) + + const select = wrapper.findComponent({ name: 'ElSelect' }) + const selectVm = select.vm as any + const input = wrapper.find('input') + input.element.focus() + + selectVm.onInput({ + target: { + value: '蚵仔煎', + }, + }) + + vi.runAllTimers() + await nextTick() + expect(selectVm.states.hoveringIndex).toBe(2) + + vi.useRealTimers() + }) + }) }) diff --git a/packages/components/select/src/useSelect.ts b/packages/components/select/src/useSelect.ts index 5301329274..70d1cff274 100644 --- a/packages/components/select/src/useSelect.ts +++ b/packages/components/select/src/useSelect.ts @@ -5,7 +5,6 @@ import { onMounted, reactive, ref, - toRaw, watch, watchEffect, } from 'vue' @@ -396,8 +395,9 @@ export const useSelect = (props: ISelectProps, emit) => { ) const userCreatedOption = optionsInDropdown.find((n) => n.created) const firstOriginOption = optionsInDropdown[0] + const valueList = optionsArray.value.map((item) => item.value) states.hoveringIndex = getValueIndex( - optionsArray.value, + valueList, userCreatedOption || firstOriginOption ) } @@ -563,7 +563,7 @@ export const useSelect = (props: ISelectProps, emit) => { const handleOptionSelect = (option) => { if (props.multiple) { const value = ensureArray(props.modelValue ?? []).slice() - const optionIndex = getValueIndex(value, option.value) + const optionIndex = getValueIndex(value, option) if (optionIndex > -1) { value.splice(optionIndex, 1) } else if ( @@ -592,19 +592,12 @@ export const useSelect = (props: ISelectProps, emit) => { }) } - const getValueIndex = (arr: any[] = [], value) => { - if (!isObject(value)) return arr.indexOf(value) + const getValueIndex = (arr: any[] = [], option) => { + if (!isObject(option?.value)) return arr.indexOf(option.value) - const valueKey = props.valueKey - let index = -1 - arr.some((item, i) => { - if (toRaw(get(item, valueKey)) === get(value, valueKey)) { - index = i - return true - } - return false + return arr.findIndex((item) => { + return isEqual(get(item, props.valueKey), getValueKey(option)) }) - return index } const scrollToOption = (option) => {