diff --git a/packages/runtime-dom/__tests__/directives/vModel.spec.ts b/packages/runtime-dom/__tests__/directives/vModel.spec.ts index a1d729be4..8bd4b5797 100644 --- a/packages/runtime-dom/__tests__/directives/vModel.spec.ts +++ b/packages/runtime-dom/__tests__/directives/vModel.spec.ts @@ -884,18 +884,21 @@ describe('vModel', () => { foo.selected = true triggerEvent('change', input) await nextTick() + expect(data.value).toBeInstanceOf(Set) expect(data.value).toMatchObject(new Set(['foo'])) foo.selected = false bar.selected = true triggerEvent('change', input) await nextTick() + expect(data.value).toBeInstanceOf(Set) expect(data.value).toMatchObject(new Set(['bar'])) foo.selected = true bar.selected = true triggerEvent('change', input) await nextTick() + expect(data.value).toBeInstanceOf(Set) expect(data.value).toMatchObject(new Set(['foo', 'bar'])) foo.selected = false diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 78a5b130f..a157177f7 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -118,11 +118,13 @@ export const vModelCheckbox: ModelDirective = { assign(filtered) } } else if (isSet(modelValue)) { + const cloned = new Set(modelValue) if (checked) { - modelValue.add(elementValue) + cloned.add(elementValue) } else { - modelValue.delete(elementValue) + cloned.delete(elementValue) } + assign(cloned) } else { assign(getCheckboxValue(el, checked)) } @@ -168,7 +170,8 @@ export const vModelRadio: ModelDirective = { } export const vModelSelect: ModelDirective = { - created(el, { modifiers: { number } }, vnode) { + created(el, { value, modifiers: { number } }, vnode) { + const isSetModel = isSet(value) addEventListener(el, 'change', () => { const selectedVal = Array.prototype.filter .call(el.options, (o: HTMLOptionElement) => o.selected) @@ -176,7 +179,13 @@ export const vModelSelect: ModelDirective = { (o: HTMLOptionElement) => number ? toNumber(getValue(o)) : getValue(o) ) - el._assign(el.multiple ? selectedVal : selectedVal[0]) + el._assign( + el.multiple + ? isSetModel + ? new Set(selectedVal) + : selectedVal + : selectedVal[0] + ) }) el._assign = getModelAssigner(vnode) },