Skip to content

Commit c3ce9fe

Browse files
authored
fix(runtime-dom): avoid unnecessary prop patch for checkbox (#11657)
close #11647
1 parent fe07f70 commit c3ce9fe

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

packages/runtime-dom/__tests__/patchProps.spec.ts

+44-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { patchProp } from '../src/patchProp'
2-
import { h, nextTick, ref, render } from '../src'
2+
import {
3+
h,
4+
nextTick,
5+
ref,
6+
render,
7+
vModelCheckbox,
8+
withDirectives,
9+
} from '../src'
310

411
describe('runtime-dom: props patching', () => {
512
test('basic', () => {
@@ -351,4 +358,40 @@ describe('runtime-dom: props patching', () => {
351358
expect(el.translate).toBeFalsy()
352359
expect(el.getAttribute('translate')).toBe('no')
353360
})
361+
362+
// #11647
363+
test('should not trigger input mutation when `value` is `undefined`', async () => {
364+
const fn = vi.fn()
365+
const comp = {
366+
setup() {
367+
const checked = ref()
368+
return () =>
369+
withDirectives(
370+
h('input', {
371+
type: 'checkbox',
372+
value: undefined,
373+
'onUpdate:modelValue': (value: any) => {
374+
checked.value = value
375+
},
376+
}),
377+
[[vModelCheckbox, checked.value]],
378+
)
379+
},
380+
}
381+
382+
const root = document.createElement('div')
383+
render(h(comp), root)
384+
document.body.append(root)
385+
386+
const el = root.children[0] as HTMLInputElement
387+
const observer = new MutationObserver(fn)
388+
observer.observe(el, {
389+
attributes: true,
390+
})
391+
392+
el.click()
393+
await nextTick()
394+
395+
expect(fn).toBeCalledTimes(0)
396+
})
354397
})

packages/runtime-dom/src/modules/props.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ export function patchDOMProp(
3333
// compare against its attribute value instead.
3434
const oldValue =
3535
tag === 'OPTION' ? el.getAttribute('value') || '' : el.value
36-
const newValue = value == null ? '' : String(value)
36+
const newValue =
37+
value == null
38+
? // #11647: value should be set as empty string for null and undefined,
39+
// but <input type="checkbox"> should be set as 'on'.
40+
el.type === 'checkbox'
41+
? 'on'
42+
: ''
43+
: String(value)
3744
if (oldValue !== newValue || !('_value' in el)) {
3845
el.value = newValue
3946
}

0 commit comments

Comments
 (0)