From c939827cd8881725a3085696269b290ca1bc4948 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Sun, 19 Jul 2020 11:04:33 +0800 Subject: [PATCH] fix(runtime-core): hosited node hmr should look up correct el fix #1626 --- packages/runtime-core/src/renderer.ts | 9 ++++++--- packages/runtime-dom/src/nodeOps.ts | 12 ++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 7f74d434326..17dd08b07df 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -119,6 +119,7 @@ export interface RendererOptions< anchor: HostNode | null, isSVG: boolean ): HostElement[] + getEqualNodeFromContainer?(container: HostElement, node: HostNode): HostNode } // Renderer Node can technically be any object in the context of core renderer @@ -398,7 +399,8 @@ function baseCreateRenderer( nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, - insertStaticContent: hostInsertStaticContent + insertStaticContent: hostInsertStaticContent, + getEqualNodeFromContainer: hostGetEqualNodeFromContainer } = options // Note: functions inside this closure should use `const xxx = () => {}` @@ -651,16 +653,17 @@ function baseCreateRenderer( // never patched (because they are not collected as dynamic nodes), but // they can be udpated during HMR. In this case just mount it as new // and remove the stale DOM tree. + const el = hostGetEqualNodeFromContainer!(container, n1.el!) mountElement( n2, container, - n1.el, + el, parentComponent, parentSuspense, isSVG, optimized ) - hostRemove(n1.el!) + hostRemove(el) } else { patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized) } diff --git a/packages/runtime-dom/src/nodeOps.ts b/packages/runtime-dom/src/nodeOps.ts index 72aa25a3930..891c23d0fea 100644 --- a/packages/runtime-dom/src/nodeOps.ts +++ b/packages/runtime-dom/src/nodeOps.ts @@ -69,5 +69,17 @@ export const nodeOps: Omit, 'patchProp'> = { node = temp.firstChild as Element } return [first, last] + }, + + getEqualNodeFromContainer(container, node) { + const parentNode = node.parentNode + if (parentNode === container) { + return node + } else { + const index = Array.prototype.slice + .call(parentNode!.children) + .indexOf(node) + return container.children[index] + } } }