From db374e54c9f5e07324728b85c74eca84e28dd352 Mon Sep 17 00:00:00 2001 From: yangxiuxiu <79584569+yangxiuxiu1115@users.noreply.github.com> Date: Thu, 28 Mar 2024 22:09:16 +0800 Subject: [PATCH] fix(runtime-dom): `v-model` string/number coercion for multiselect options (#10576) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RicardoErii <‘1974364190@qq.com’> Co-authored-by: yangchangtao --- .../__tests__/directives/vModel.spec.ts | 32 +++++++++++++++++++ packages/runtime-dom/src/directives/vModel.ts | 4 +-- 2 files changed, 33 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..e002e2e10da 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -242,9 +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.includes( - number ? looseToNumber(optionValue) : optionValue, - ) + option.selected = value.some(v => String(v) === String(optionValue)) } else { option.selected = looseIndexOf(value, optionValue) > -1 }