fix(runtime-dom): avoid unnecessary prop patch for checkbox (#11657)

close #11647
This commit is contained in:
Alex Liu 2024-09-03 21:10:18 +08:00 committed by GitHub
parent fe07f70736
commit c3ce9fe3d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 2 deletions

View File

@ -1,5 +1,12 @@
import { patchProp } from '../src/patchProp'
import { h, nextTick, ref, render } from '../src'
import {
h,
nextTick,
ref,
render,
vModelCheckbox,
withDirectives,
} from '../src'
describe('runtime-dom: props patching', () => {
test('basic', () => {
@ -351,4 +358,40 @@ describe('runtime-dom: props patching', () => {
expect(el.translate).toBeFalsy()
expect(el.getAttribute('translate')).toBe('no')
})
// #11647
test('should not trigger input mutation when `value` is `undefined`', async () => {
const fn = vi.fn()
const comp = {
setup() {
const checked = ref()
return () =>
withDirectives(
h('input', {
type: 'checkbox',
value: undefined,
'onUpdate:modelValue': (value: any) => {
checked.value = value
},
}),
[[vModelCheckbox, checked.value]],
)
},
}
const root = document.createElement('div')
render(h(comp), root)
document.body.append(root)
const el = root.children[0] as HTMLInputElement
const observer = new MutationObserver(fn)
observer.observe(el, {
attributes: true,
})
el.click()
await nextTick()
expect(fn).toBeCalledTimes(0)
})
})

View File

@ -33,7 +33,14 @@ export function patchDOMProp(
// compare against its attribute value instead.
const oldValue =
tag === 'OPTION' ? el.getAttribute('value') || '' : el.value
const newValue = value == null ? '' : String(value)
const newValue =
value == null
? // #11647: value should be set as empty string for null and undefined,
// but <input type="checkbox"> should be set as 'on'.
el.type === 'checkbox'
? 'on'
: ''
: String(value)
if (oldValue !== newValue || !('_value' in el)) {
el.value = newValue
}