From 6c8bfa10189d1a5a6837d2e25a9451889a0e19d6 Mon Sep 17 00:00:00 2001 From: underfin <2218301630@qq.com> Date: Tue, 16 Jun 2020 04:46:29 +0800 Subject: [PATCH] fix(runtime-core): fix parent el update on nested HOC self-update (#1360) fix #1357 --- .../__tests__/rendererComponent.spec.ts | 44 +++++++++++++++++++ packages/runtime-core/src/renderer.ts | 4 +- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 packages/runtime-core/__tests__/rendererComponent.spec.ts diff --git a/packages/runtime-core/__tests__/rendererComponent.spec.ts b/packages/runtime-core/__tests__/rendererComponent.spec.ts new file mode 100644 index 00000000000..2bd611334cc --- /dev/null +++ b/packages/runtime-core/__tests__/rendererComponent.spec.ts @@ -0,0 +1,44 @@ +import { + ref, + h, + render, + nodeOps, + serializeInner, + nextTick, + VNode +} from '@vue/runtime-test' + +describe('renderer: component', () => { + test('should update parent(hoc) component host el when child component self update', async () => { + const value = ref(true) + let parentVnode: VNode + let childVnode1: VNode + let childVnode2: VNode + + const Parent = { + render: () => { + // let Parent first rerender + console.log(value.value) + return (parentVnode = h(Child)) + } + } + + const Child = { + render: () => { + return value.value + ? (childVnode1 = h('div')) + : (childVnode2 = h('span')) + } + } + + const root = nodeOps.createElement('div') + render(h(Parent), root) + expect(serializeInner(root)).toBe(`
`) + expect(parentVnode!.el).toBe(childVnode1!.el) + + value.value = false + await nextTick() + expect(serializeInner(root)).toBe(``) + expect(parentVnode!.el).toBe(childVnode2!.el) + }) +}) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 1d8bc712b59..edc00d1750d 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -1216,6 +1216,7 @@ function baseCreateRenderer( // no update needed. just copy over properties n2.component = n1.component n2.el = n1.el + instance.vnode = n2 } } @@ -1304,6 +1305,7 @@ function baseCreateRenderer( // This is triggered by mutation of component's own state (next: null) // OR parent calling processComponent (next: VNode) let { next, bu, u, parent, vnode } = instance + let originNext = next let vnodeHook: VNodeHook | null | undefined if (__DEV__) { pushWarningContext(next || instance.vnode) @@ -1355,7 +1357,7 @@ function baseCreateRenderer( endMeasure(instance, `patch`) } next.el = nextTree.el - if (next === null) { + if (originNext === null) { // self-triggered update. In case of HOC, update parent component // vnode el. HOC is indicated by parent instance's subTree pointing // to child component's vnode