Skip to content

Commit 104b940

Browse files
committed
handle component root patch edge case (transition + keep-alive + HOC) (fix #4590)
1 parent fe02bc3 commit 104b940

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

Diff for: src/core/vdom/patch.js

+30-23
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,23 @@ export function createPatchFunction (backend) {
178178
}
179179
}
180180

181+
function initComponent (vnode, insertedVnodeQueue) {
182+
if (vnode.data.pendingInsert) {
183+
insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert)
184+
}
185+
vnode.elm = vnode.componentInstance.$el
186+
if (isPatchable(vnode)) {
187+
invokeCreateHooks(vnode, insertedVnodeQueue)
188+
setScope(vnode)
189+
} else {
190+
// empty component root.
191+
// skip all element-related modules except for ref (#3455)
192+
registerRef(vnode)
193+
// make sure to invoke the insert hook
194+
insertedVnodeQueue.push(vnode)
195+
}
196+
}
197+
181198
function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
182199
let i
183200
// hack for #4339: a reactivated component with inner transition
@@ -238,23 +255,6 @@ export function createPatchFunction (backend) {
238255
}
239256
}
240257

241-
function initComponent (vnode, insertedVnodeQueue) {
242-
if (vnode.data.pendingInsert) {
243-
insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert)
244-
}
245-
vnode.elm = vnode.componentInstance.$el
246-
if (isPatchable(vnode)) {
247-
invokeCreateHooks(vnode, insertedVnodeQueue)
248-
setScope(vnode)
249-
} else {
250-
// empty component root.
251-
// skip all element-related modules except for ref (#3455)
252-
registerRef(vnode)
253-
// make sure to invoke the insert hook
254-
insertedVnodeQueue.push(vnode)
255-
}
256-
}
257-
258258
// set scope id attribute for scoped CSS.
259259
// this is implemented as a special case to avoid the overhead
260260
// of going through the normal attribute patching process.
@@ -549,7 +549,6 @@ export function createPatchFunction (backend) {
549549
return
550550
}
551551

552-
let elm, parent
553552
let isInitialPatch = false
554553
const insertedVnodeQueue = []
555554

@@ -590,9 +589,17 @@ export function createPatchFunction (backend) {
590589
oldVnode = emptyNodeAt(oldVnode)
591590
}
592591
// replacing existing element
593-
elm = oldVnode.elm
594-
parent = nodeOps.parentNode(elm)
595-
createElm(vnode, insertedVnodeQueue, parent, nodeOps.nextSibling(elm))
592+
const oldElm = oldVnode.elm
593+
const parentElm = nodeOps.parentNode(oldElm)
594+
createElm(
595+
vnode,
596+
insertedVnodeQueue,
597+
// extremely rare edge case: do not insert if old element is in a
598+
// leaving transition. Only happens when combining transition +
599+
// keep-alive + HOCs. (#4590)
600+
oldElm._leaveCb ? null : parentElm,
601+
nodeOps.nextSibling(oldElm)
602+
)
596603

597604
if (vnode.parent) {
598605
// component root element replaced.
@@ -609,8 +616,8 @@ export function createPatchFunction (backend) {
609616
}
610617
}
611618

612-
if (parent !== null) {
613-
removeVnodes(parent, [oldVnode], 0, 0)
619+
if (parentElm !== null) {
620+
removeVnodes(parentElm, [oldVnode], 0, 0)
614621
} else if (isDef(oldVnode.tag)) {
615622
invokeDestroyHook(oldVnode)
616623
}

0 commit comments

Comments
 (0)