Skip to content

Commit 66c5a55

Browse files
committed
fix(hmr): ensure static nodes inherit DOM element in hmr mode
fix #1156
1 parent a165d82 commit 66c5a55

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

packages/runtime-core/src/renderer.ts

+35-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
isSameVNodeType,
1111
Static,
1212
VNodeNormalizedRef,
13-
VNodeHook
13+
VNodeHook,
14+
isVNode
1415
} from './vnode'
1516
import {
1617
ComponentInternalInstance,
@@ -33,7 +34,8 @@ import {
3334
ShapeFlags,
3435
NOOP,
3536
hasOwn,
36-
invokeArrayFns
37+
invokeArrayFns,
38+
isArray
3739
} from '@vue/shared'
3840
import {
3941
queueJob,
@@ -769,6 +771,9 @@ function baseCreateRenderer(
769771
parentSuspense,
770772
areChildrenSVG
771773
)
774+
if (__DEV__ && parentComponent && parentComponent.type.__hmrId) {
775+
traverseStaticChildren(n1, n2)
776+
}
772777
} else if (!optimized) {
773778
// full diff
774779
patchChildren(
@@ -933,6 +938,9 @@ function baseCreateRenderer(
933938
parentSuspense,
934939
isSVG
935940
)
941+
if (__DEV__ && parentComponent && parentComponent.type.__hmrId) {
942+
traverseStaticChildren(n1, n2)
943+
}
936944
} else {
937945
// keyed / unkeyed, or manual fragments.
938946
// for keyed & unkeyed, since they are compiler generated from v-for,
@@ -1944,6 +1952,31 @@ function baseCreateRenderer(
19441952
}
19451953
}
19461954

1955+
/**
1956+
* #1156
1957+
* When a component is HMR-enabled, we need to make sure that all static nodes
1958+
* inside a block also inherit the DOM element from the previous tree so that
1959+
* HMR updates (which are full updates) can retrieve the element for patching.
1960+
*
1961+
* Dev only.
1962+
*/
1963+
const traverseStaticChildren = (n1: VNode, n2: VNode) => {
1964+
const ch1 = n1.children
1965+
const ch2 = n2.children
1966+
if (isArray(ch1) && isArray(ch2)) {
1967+
for (let i = 0; i < ch1.length; i++) {
1968+
const c1 = ch1[i]
1969+
const c2 = ch2[i]
1970+
if (isVNode(c1) && isVNode(c2) && !c2.dynamicChildren) {
1971+
if (c2.patchFlag <= 0) {
1972+
c2.el = c1.el
1973+
}
1974+
traverseStaticChildren(c1, c2)
1975+
}
1976+
}
1977+
}
1978+
}
1979+
19471980
const render: RootRenderFunction = (vnode, container) => {
19481981
if (vnode == null) {
19491982
if (container._vnode) {

0 commit comments

Comments
 (0)