Skip to content

Commit 5b3f1e8

Browse files
authored
fix(runtime-core): patchChildren first in patchElement (#4313)
1 parent cd2d984 commit 5b3f1e8

File tree

3 files changed

+57
-35
lines changed

3 files changed

+57
-35
lines changed

packages/runtime-core/src/renderer.ts

+29-29
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,35 @@ function baseCreateRenderer(
840840
dynamicChildren = null
841841
}
842842

843+
const areChildrenSVG = isSVG && n2.type !== 'foreignObject'
844+
if (dynamicChildren) {
845+
patchBlockChildren(
846+
n1.dynamicChildren!,
847+
dynamicChildren,
848+
el,
849+
parentComponent,
850+
parentSuspense,
851+
areChildrenSVG,
852+
slotScopeIds
853+
)
854+
if (__DEV__ && parentComponent && parentComponent.type.__hmrId) {
855+
traverseStaticChildren(n1, n2)
856+
}
857+
} else if (!optimized) {
858+
// full diff
859+
patchChildren(
860+
n1,
861+
n2,
862+
el,
863+
null,
864+
parentComponent,
865+
parentSuspense,
866+
areChildrenSVG,
867+
slotScopeIds,
868+
false
869+
)
870+
}
871+
843872
if (patchFlag > 0) {
844873
// the presence of a patchFlag means this element's render code was
845874
// generated by the compiler and can take the fast path.
@@ -922,35 +951,6 @@ function baseCreateRenderer(
922951
)
923952
}
924953

925-
const areChildrenSVG = isSVG && n2.type !== 'foreignObject'
926-
if (dynamicChildren) {
927-
patchBlockChildren(
928-
n1.dynamicChildren!,
929-
dynamicChildren,
930-
el,
931-
parentComponent,
932-
parentSuspense,
933-
areChildrenSVG,
934-
slotScopeIds
935-
)
936-
if (__DEV__ && parentComponent && parentComponent.type.__hmrId) {
937-
traverseStaticChildren(n1, n2)
938-
}
939-
} else if (!optimized) {
940-
// full diff
941-
patchChildren(
942-
n1,
943-
n2,
944-
el,
945-
null,
946-
parentComponent,
947-
parentSuspense,
948-
areChildrenSVG,
949-
slotScopeIds,
950-
false
951-
)
952-
}
953-
954954
if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
955955
queuePostRenderEffect(() => {
956956
vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1)

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

+22
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,26 @@ describe('runtime-dom: props patching', () => {
192192
patchProp(el, 'size', 100, null)
193193
expect(el.getAttribute('size')).toBe(null)
194194
})
195+
196+
test('patch value for select', () => {
197+
const root = document.createElement('div')
198+
render(
199+
h('select', { value: 'foo' }, [
200+
h('option', { value: 'foo' }, 'foo'),
201+
h('option', { value: 'bar' }, 'bar')
202+
]),
203+
root
204+
)
205+
const el = root.children[0] as HTMLSelectElement
206+
expect(el.value).toBe('foo')
207+
208+
render(
209+
h('select', { value: 'baz' }, [
210+
h('option', { value: 'foo' }, 'foo'),
211+
h('option', { value: 'baz' }, 'baz')
212+
]),
213+
root
214+
)
215+
expect(el.value).toBe('baz')
216+
})
195217
})

packages/runtime-test/__tests__/testRuntime.spec.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,17 @@ describe('test renderer', () => {
103103
expect(updateOps.length).toBe(2)
104104

105105
expect(updateOps[0]).toEqual({
106-
type: NodeOpTypes.PATCH,
106+
type: NodeOpTypes.SET_ELEMENT_TEXT,
107107
targetNode: root.children[0],
108-
propKey: 'id',
109-
propPrevValue: 'test',
110-
propNextValue: 'foo'
108+
text: 'bar'
111109
})
112110

113111
expect(updateOps[1]).toEqual({
114-
type: NodeOpTypes.SET_ELEMENT_TEXT,
112+
type: NodeOpTypes.PATCH,
115113
targetNode: root.children[0],
116-
text: 'bar'
114+
propKey: 'id',
115+
propPrevValue: 'test',
116+
propNextValue: 'foo'
117117
})
118118
})
119119

0 commit comments

Comments
 (0)