Skip to content

Commit

Permalink
fix(runtime-dom): prevent unnecessary updates in v-model checkbox whe…
Browse files Browse the repository at this point in the history
…n value is unchanged (#12146)

close #12144
  • Loading branch information
jh-leong authored Oct 11, 2024
1 parent d82fa61 commit ea943af
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/runtime-dom/src/directives/vModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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))
}

Expand Down
57 changes: 57 additions & 0 deletions packages/vue/__tests__/e2e/vModel.spec.ts
Original file line number Diff line number Diff line change
@@ -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)
})

0 comments on commit ea943af

Please sign in to comment.