fix(runtime-dom): prevent unnecessary updates in v-model checkbox when value is unchanged (#12146)

close #12144
This commit is contained in:
Tycho 2024-10-11 21:00:08 +08:00 committed by GitHub
parent d82fa611e8
commit ea943afe40
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 1 deletions

View File

@ -160,7 +160,7 @@ export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
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))
}

View File

@ -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(`<div id="app"></div>`)
})
// #12144
test('checkbox click with v-model', async () => {
await page().evaluate(() => {
const { createApp } = (window as any).Vue
createApp({
template: `
<label>
<input
id="first"
type="checkbox"
v-model="first"/>
First
</label>
<br>
<label>
<input
id="second"
type="checkbox"
v-model="second"
@click="secondClick"/>
Second
</label>
`,
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)
})