From e853eb112ef6f644669ea501b77b25107e391cc6 Mon Sep 17 00:00:00 2001 From: tycho Date: Thu, 10 Oct 2024 21:22:32 +0800 Subject: [PATCH 1/3] fix(runtime-dom): prevent unnecessary updates in v-model checkbox when value is unchanged --- packages/runtime-dom/src/directives/vModel.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 5a27b245a66..5057e16d472 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -160,7 +160,7 @@ export const vModelCheckbox: ModelDirective = { function setChecked( el: HTMLInputElement, - { value }: DirectiveBinding, + { value, oldValue }: DirectiveBinding, vnode: VNode, ) { // store the v-model value on the element so it can be accessed by the @@ -173,6 +173,7 @@ function setChecked( } else if (isSet(value)) { checked = value.has(vnode.props!.value) } else { + if (value === oldValue) return checked = looseEqual(value, getCheckboxValue(el, true)) } From ad8aa356ffd9b8a2afe9304bb6e82ced817ecd66 Mon Sep 17 00:00:00 2001 From: daiwei Date: Fri, 11 Oct 2024 14:54:41 +0800 Subject: [PATCH 2/3] test: add e2e test --- packages/vue/__tests__/e2e/vModel.spec.ts | 57 +++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 packages/vue/__tests__/e2e/vModel.spec.ts diff --git a/packages/vue/__tests__/e2e/vModel.spec.ts b/packages/vue/__tests__/e2e/vModel.spec.ts new file mode 100644 index 00000000000..ccd1bb4c560 --- /dev/null +++ b/packages/vue/__tests__/e2e/vModel.spec.ts @@ -0,0 +1,57 @@ +import path from 'node:path' +import { setupPuppeteer } from './e2eUtils' + +const { page, click, isChecked } = setupPuppeteer() +import { nextTick } from 'vue' + +beforeEach(async () => { + await page().addScriptTag({ + path: path.resolve(__dirname, '../../dist/vue.global.js'), + }) + await page().setContent(`
`) +}) + +// #12144 +test('checkbox click with v-model', async () => { + await page().evaluate(() => { + const { createApp } = (window as any).Vue + createApp({ + template: ` + +
+ + `, + data() { + return { + first: true, + second: false, + } + }, + methods: { + secondClick(this: any) { + this.first = false + }, + }, + }).mount('#app') + }) + + expect(await isChecked('#first')).toBe(true) + expect(await isChecked('#second')).toBe(false) + await click('#second') + await nextTick() + expect(await isChecked('#first')).toBe(false) + expect(await isChecked('#second')).toBe(true) +}) From 6e77a7f115525291d8a3ce8e86ac824245a36b21 Mon Sep 17 00:00:00 2001 From: daiwei Date: Fri, 11 Oct 2024 14:55:39 +0800 Subject: [PATCH 3/3] test: format --- packages/vue/__tests__/e2e/vModel.spec.ts | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/vue/__tests__/e2e/vModel.spec.ts b/packages/vue/__tests__/e2e/vModel.spec.ts index ccd1bb4c560..e1a06bda532 100644 --- a/packages/vue/__tests__/e2e/vModel.spec.ts +++ b/packages/vue/__tests__/e2e/vModel.spec.ts @@ -17,22 +17,22 @@ test('checkbox click with v-model', async () => { const { createApp } = (window as any).Vue createApp({ template: ` - -
- + +
+ `, data() { return {