From 1a00d6a17a2a4c310de792721371637d70c4e200 Mon Sep 17 00:00:00 2001 From: RicardoErii <‘1974364190@qq.com’> Date: Sun, 24 Mar 2024 01:09:14 +0800 Subject: [PATCH 1/3] fix(runtime-core): vModelSelect type compatibility --- .../__tests__/directives/vModel.spec.ts | 32 +++++++++++++++++++ packages/runtime-dom/src/directives/vModel.ts | 10 ++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/packages/runtime-dom/__tests__/directives/vModel.spec.ts b/packages/runtime-dom/__tests__/directives/vModel.spec.ts index 6cc7b53e2c2..d6398f37321 100644 --- a/packages/runtime-dom/__tests__/directives/vModel.spec.ts +++ b/packages/runtime-dom/__tests__/directives/vModel.spec.ts @@ -1237,4 +1237,36 @@ describe('vModel', () => { await nextTick() expect(data.value).toEqual('使用拼音输入') }) + + it('multiple select (model is number, option value is string)', async () => { + const component = defineComponent({ + data() { + return { + value: [1, 2], + } + }, + render() { + return [ + withVModel( + h( + 'select', + { + multiple: true, + 'onUpdate:modelValue': setValue.bind(this), + }, + [h('option', { value: '1' }), h('option', { value: '2' })], + ), + this.value, + ), + ] + }, + }) + render(h(component), root) + + await nextTick() + const [foo, bar] = root.querySelectorAll('option') + + expect(foo.selected).toEqual(true) + expect(bar.selected).toEqual(true) + }) }) diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 9e94810d8cd..8fefa494382 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -242,9 +242,13 @@ function setSelected(el: HTMLSelectElement, value: any, number: boolean) { const optionType = typeof optionValue // fast path for string / number values if (optionType === 'string' || optionType === 'number') { - option.selected = value.includes( - number ? looseToNumber(optionValue) : optionValue, - ) + option.selected = !!value.find(v => { + let value = optionValue + if (number) { + value = looseToNumber(optionValue) + } + return looseEqual(value, v) + }) } else { option.selected = looseIndexOf(value, optionValue) > -1 } From 2ffb7da22a42a9aa71d6c39e4452e01fe3871389 Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Mon, 25 Mar 2024 10:42:38 +0800 Subject: [PATCH 2/3] perf: perf --- packages/runtime-dom/src/directives/vModel.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 8fefa494382..e9b67642521 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -243,11 +243,15 @@ function setSelected(el: HTMLSelectElement, value: any, number: boolean) { // fast path for string / number values if (optionType === 'string' || optionType === 'number') { option.selected = !!value.find(v => { - let value = optionValue + let val = optionValue if (number) { - value = looseToNumber(optionValue) + val = looseToNumber(optionValue) } - return looseEqual(value, v) + const valType = typeof v + if (valType === optionType) { + return val === v + } + return looseEqual(val, v) }) } else { option.selected = looseIndexOf(value, optionValue) > -1 From 782026b6e1bb967e1d76c60f5f59d2316997780b Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Tue, 26 Mar 2024 10:30:29 +0800 Subject: [PATCH 3/3] perf: perf --- packages/runtime-dom/src/directives/vModel.ts | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index e9b67642521..e002e2e10da 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -242,17 +242,7 @@ function setSelected(el: HTMLSelectElement, value: any, number: boolean) { const optionType = typeof optionValue // fast path for string / number values if (optionType === 'string' || optionType === 'number') { - option.selected = !!value.find(v => { - let val = optionValue - if (number) { - val = looseToNumber(optionValue) - } - const valType = typeof v - if (valType === optionType) { - return val === v - } - return looseEqual(val, v) - }) + option.selected = value.some(v => String(v) === String(optionValue)) } else { option.selected = looseIndexOf(value, optionValue) > -1 }