fix(vModel): skip value update in mounted hook if value was previously set

This commit is contained in:
daiwei 2024-11-28 11:53:16 +08:00
parent 5a5406d002
commit 001db1e3c2
1 changed files with 8 additions and 2 deletions

View File

@ -40,7 +40,7 @@ function onCompositionEnd(e: Event) {
const assignKey: unique symbol = Symbol('_assign') const assignKey: unique symbol = Symbol('_assign')
type ModelDirective<T, Modifiers extends string = string> = ObjectDirective< type ModelDirective<T, Modifiers extends string = string> = ObjectDirective<
T & { [assignKey]: AssignerFn; _assigning?: boolean }, T & { [assignKey]: AssignerFn; _assigning?: boolean; _initialValue?: any },
any, any,
Modifiers Modifiers
> >
@ -52,6 +52,7 @@ export const vModelText: ModelDirective<
'trim' | 'number' | 'lazy' 'trim' | 'number' | 'lazy'
> = { > = {
created(el, { modifiers: { lazy, trim, number } }, vnode) { created(el, { modifiers: { lazy, trim, number } }, vnode) {
el._initialValue = el.value
el[assignKey] = getModelAssigner(vnode) el[assignKey] = getModelAssigner(vnode)
const castToNumber = const castToNumber =
number || (vnode.props && vnode.props.type === 'number') number || (vnode.props && vnode.props.type === 'number')
@ -83,6 +84,7 @@ export const vModelText: ModelDirective<
}, },
// set value on mounted so it's after min/max for type="range" // set value on mounted so it's after min/max for type="range"
mounted(el, { value }) { mounted(el, { value }) {
if (el._initialValue !== el.value) return
el.value = value == null ? '' : value el.value = value == null ? '' : value
}, },
beforeUpdate( beforeUpdate(
@ -122,6 +124,7 @@ export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
deep: true, deep: true,
created(el, _, vnode) { created(el, _, vnode) {
el[assignKey] = getModelAssigner(vnode) el[assignKey] = getModelAssigner(vnode)
el._initialValue = el.checked
addEventListener(el, 'change', () => { addEventListener(el, 'change', () => {
const modelValue = (el as any)._modelValue const modelValue = (el as any)._modelValue
const elementValue = getValue(el) const elementValue = getValue(el)
@ -151,7 +154,10 @@ export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
}) })
}, },
// set initial checked on mount to wait for true-value/false-value // set initial checked on mount to wait for true-value/false-value
mounted: setChecked, mounted(el, binding, vnode) {
if (el._initialValue !== el.checked) return
setChecked(el, binding, vnode)
},
beforeUpdate(el, binding, vnode) { beforeUpdate(el, binding, vnode) {
el[assignKey] = getModelAssigner(vnode) el[assignKey] = getModelAssigner(vnode)
setChecked(el, binding, vnode) setChecked(el, binding, vnode)