diff --git a/packages/runtime-dom/__tests__/directives/vModel.spec.ts b/packages/runtime-dom/__tests__/directives/vModel.spec.ts index a1d729be4..255f49c8e 100644 --- a/packages/runtime-dom/__tests__/directives/vModel.spec.ts +++ b/packages/runtime-dom/__tests__/directives/vModel.spec.ts @@ -6,7 +6,8 @@ import { vModelDynamic, withDirectives, VNode, - ref + ref, + reactive } from '@vue/runtime-dom' const triggerEvent = (type: string, el: Element) => { @@ -433,6 +434,78 @@ describe('vModel', () => { expect(bar.checked).toEqual(false) }) + it(`should support the reactive array in setup as a checkbox model`, async () => { + const value = reactive([]) + + const component = defineComponent({ + setup() { + return () => { + return [ + withVModel( + h('input', { + type: 'checkbox', + class: 'foo', + value: 'foo', + 'onUpdate:modelValue': setValue.bind(this) + }), + value + ), + withVModel( + h('input', { + type: 'checkbox', + class: 'bar', + value: 'bar', + 'onUpdate:modelValue': setValue.bind(this) + }), + value + ) + ] + } + } + }) + render(h(component), root) + + const foo = root.querySelector('.foo') + const bar = root.querySelector('.bar') + + foo.checked = true + triggerEvent('change', foo) + await nextTick() + expect(value).toMatchObject(['foo']) + + bar.checked = true + triggerEvent('change', bar) + await nextTick() + expect(value).toMatchObject(['foo', 'bar']) + + bar.checked = false + triggerEvent('change', bar) + await nextTick() + expect(value).toMatchObject(['foo']) + + foo.checked = false + triggerEvent('change', foo) + await nextTick() + expect(value).toMatchObject([]) + + value.length = 0 + value.push('foo') + await nextTick() + expect(bar.checked).toEqual(false) + expect(foo.checked).toEqual(true) + + value.length = 0 + value.push('bar') + await nextTick() + expect(foo.checked).toEqual(false) + expect(bar.checked).toEqual(true) + + value.length = 0 + await nextTick() + expect(foo.checked).toEqual(false) + expect(bar.checked).toEqual(false) + }) + it(`should support Set as a checkbox model`, async () => { const component = defineComponent({ data() { diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 78a5b130f..ed5252039 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -111,11 +111,9 @@ export const vModelCheckbox: ModelDirective = { const index = looseIndexOf(modelValue, elementValue) const found = index !== -1 if (checked && !found) { - assign(modelValue.concat(elementValue)) + modelValue.push(elementValue) } else if (!checked && found) { - const filtered = [...modelValue] - filtered.splice(index, 1) - assign(filtered) + modelValue.splice(index, 1) } } else if (isSet(modelValue)) { if (checked) {