fix(components): [select] Fix value bind object and trigger twice in form label (#15449)

* fix(components): [select] Fix value bind object

* fix(components): update

* fix(components): update
This commit is contained in:
kooriookami 2024-01-11 14:45:23 +08:00 committed by GitHub
parent 018f22f36c
commit e7c1b53da3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 10 deletions

View File

@ -159,6 +159,7 @@
@keydown.enter.stop.prevent="onKeyboardSelect"
@keydown.esc.stop.prevent="handleEsc"
@keydown.delete.stop="handleDel"
@click.stop
/>
<span
v-if="filterable"

View File

@ -480,6 +480,41 @@ describe('Select', () => {
expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe('双皮奶')
})
test('value bind object with value-key', async () => {
wrapper = _mount(
`
<el-select v-model="value" value-key="id">
<el-option
v-for="item in options"
:key="item.id"
:label="item.label"
:value="item"
/>
</el-select>
`,
() => ({
options: [
{ id: 1, label: 'Option A', desc: 'Option A - 230506' },
{ id: 2, label: 'Option B', desc: 'Option B - 230506' },
{ id: 3, label: 'Option C', desc: 'Option C - 230506' },
{ id: 4, label: 'Option D', desc: 'Option D - 230507' },
],
value: {
value: '',
},
})
)
await nextTick()
await wrapper.find(`.${WRAPPER_CLASS_NAME}`).trigger('click')
const options = getOptions()
options[2].click()
await nextTick()
expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe('Option C')
options[3].click()
await nextTick()
expect(wrapper.find(`.${PLACEHOLDER_CLASS_NAME}`).text()).toBe('Option D')
})
test('sync set value and options', async () => {
wrapper = _mount(
`
@ -783,8 +818,7 @@ describe('Select', () => {
)
const select = wrapper.findComponent({ name: 'ElSelect' })
const selectVm = select.vm as any
const input = wrapper.find('input')
await input.trigger('click')
await select.trigger('click')
expect(selectVm.states.hoveringIndex).toBe(0)
selectVm.navigateOptions('next')
expect(selectVm.states.hoveringIndex).toBe(1)
@ -862,8 +896,7 @@ describe('Select', () => {
})
const select = wrapper.findComponent({ name: 'ElSelect' })
const selectVm = select.vm as any
const input = wrapper.find('input')
await input.trigger('click')
await select.trigger('click')
expect(selectVm.states.hoveringIndex).toBe(0)
selectVm.navigateOptions('next')
expect(selectVm.states.hoveringIndex).toBe(1)
@ -896,8 +929,7 @@ describe('Select', () => {
)
const select = wrapper.findComponent({ name: 'ElSelect' })
const selectVm = select.vm as any
const input = wrapper.find('input')
await input.trigger('click')
await select.trigger('click')
expect(selectVm.states.hoveringIndex).toBe(1) // index 0 was skipped
selectVm.navigateOptions('next')

View File

@ -159,6 +159,7 @@
@compositionupdate="handleCompositionUpdate"
@compositionend="handleCompositionEnd"
@input="onInput"
@click.stop
/>
<span
v-if="filterable"

View File

@ -5,6 +5,7 @@ import {
onMounted,
reactive,
ref,
toRaw,
watch,
watchEffect,
} from 'vue'
@ -420,7 +421,7 @@ export const useSelect = (props: ISelectProps, emit) => {
for (let i = states.cachedOptions.size - 1; i >= 0; i--) {
const cachedOption = cachedOptionsArray.value[i]
const isEqualValue = isObjectValue
? getValueKey(cachedOption.value) === getValueKey(value)
? get(cachedOption.value, props.valueKey) === get(value, props.valueKey)
: cachedOption.value === value
if (isEqualValue) {
option = {
@ -554,7 +555,7 @@ export const useSelect = (props: ISelectProps, emit) => {
const handleOptionSelect = (option) => {
if (props.multiple) {
const value = (props.modelValue || []).slice()
const optionIndex = getValueIndex(value, getValueKey(option))
const optionIndex = getValueIndex(value, option.value)
if (optionIndex > -1) {
value.splice(optionIndex, 1)
} else if (
@ -586,9 +587,16 @@ export const useSelect = (props: ISelectProps, emit) => {
const getValueIndex = (arr: any[] = [], value) => {
if (!isObject(value)) return arr.indexOf(value)
return arr.findIndex((item) => {
return isEqual(getValueKey(item), getValueKey(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 index
}
const scrollToOption = (option) => {