Skip to content

Commit b3536d8

Browse files
committed
fix(runtime-dom): allow force updating value bindings for controlled inputs
fix vuejs#1471
1 parent 062835d commit b3536d8

File tree

4 files changed

+19
-9
lines changed

4 files changed

+19
-9
lines changed

packages/runtime-core/src/renderer.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export interface RendererOptions<
9696
parentSuspense?: SuspenseBoundary | null,
9797
unmountChildren?: UnmountChildrenFn
9898
): void
99+
forcePatchProp?(el: HostElement, key: string): boolean
99100
insert(el: HostNode, parent: HostElement, anchor?: HostNode | null): void
100101
remove(el: HostNode): void
101102
createElement(
@@ -383,6 +384,7 @@ function baseCreateRenderer(
383384
insert: hostInsert,
384385
remove: hostRemove,
385386
patchProp: hostPatchProp,
387+
forcePatchProp: hostForcePatchProp,
386388
createElement: hostCreateElement,
387389
createText: hostCreateText,
388390
createComment: hostCreateComment,
@@ -845,7 +847,10 @@ function baseCreateRenderer(
845847
const key = propsToUpdate[i]
846848
const prev = oldProps[key]
847849
const next = newProps[key]
848-
if (prev !== next) {
850+
if (
851+
next !== prev ||
852+
(hostForcePatchProp && hostForcePatchProp(el, key))
853+
) {
849854
hostPatchProp(
850855
el,
851856
key,
@@ -969,7 +974,10 @@ function baseCreateRenderer(
969974
if (isReservedProp(key)) continue
970975
const next = newProps[key]
971976
const prev = oldProps[key]
972-
if (next !== prev) {
977+
if (
978+
next !== prev ||
979+
(hostForcePatchProp && hostForcePatchProp(el, key))
980+
) {
973981
hostPatchProp(
974982
el,
975983
key,

packages/runtime-dom/src/directives/vModel.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,8 @@ export const vModelText: ModelDirective<
7575
addEventListener(el, 'change', onCompositionEnd)
7676
}
7777
},
78-
beforeUpdate(el, { value, oldValue, modifiers: { trim, number } }, vnode) {
78+
beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) {
7979
el._assign = getModelAssigner(vnode)
80-
if (value === oldValue) {
81-
return
82-
}
8380
if (document.activeElement === el) {
8481
if (trim && el.value.trim() === value) {
8582
return

packages/runtime-dom/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
RootHydrateFunction
1111
} from '@vue/runtime-core'
1212
import { nodeOps } from './nodeOps'
13-
import { patchProp } from './patchProp'
13+
import { patchProp, forcePatchProp } from './patchProp'
1414
// Importing from the compiler, will be tree-shaken in prod
1515
import { isFunction, isString, isHTMLTag, isSVGTag, extend } from '@vue/shared'
1616

@@ -21,7 +21,7 @@ declare module '@vue/reactivity' {
2121
}
2222
}
2323

24-
const rendererOptions = extend({ patchProp }, nodeOps)
24+
const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps)
2525

2626
// lazy create the renderer - this makes core renderer logic tree-shakable
2727
// in case the user only imports reactivity utilities from Vue.

packages/runtime-dom/src/patchProp.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ import { RendererOptions } from '@vue/runtime-core'
88

99
const nativeOnRE = /^on[a-z]/
1010

11-
export const patchProp: RendererOptions<Node, Element>['patchProp'] = (
11+
type DOMRendererOptions = RendererOptions<Node, Element>
12+
13+
export const forcePatchProp: DOMRendererOptions['forcePatchProp'] = (_, key) =>
14+
key === 'value'
15+
16+
export const patchProp: DOMRendererOptions['patchProp'] = (
1217
el,
1318
key,
1419
prevValue,

0 commit comments

Comments
 (0)