From ee44c71c1cdf3d37bae6d4c4a5db9e0b4108b724 Mon Sep 17 00:00:00 2001 From: huanghaoqun Date: Sat, 15 Feb 2020 09:58:40 +0800 Subject: [PATCH 1/3] fix(ssr): ignore empty text vnode when hydrating --- src/core/vdom/patch.js | 8 +++++++- test/unit/modules/vdom/patch/hydration.spec.js | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/core/vdom/patch.js b/src/core/vdom/patch.js index 2052df913b3..92d6d307227 100644 --- a/src/core/vdom/patch.js +++ b/src/core/vdom/patch.js @@ -23,6 +23,7 @@ import { isDef, isUndef, isTrue, + isFalse, makeMap, isRegExp, isPrimitive @@ -643,7 +644,12 @@ export function createPatchFunction (backend) { let childrenMatch = true let childNode = elm.firstChild for (let i = 0; i < children.length; i++) { - if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue, inVPre)) { + const child = children[i] + // ignore empty text vnode + if (isUndef(child.tag) && isFalse(child.isComment) && child.text === '') { + continue + } + if (!childNode || !hydrate(childNode, child, insertedVnodeQueue, inVPre)) { childrenMatch = false break } diff --git a/test/unit/modules/vdom/patch/hydration.spec.js b/test/unit/modules/vdom/patch/hydration.spec.js index 930ad47cc81..1fb22d969a9 100644 --- a/test/unit/modules/vdom/patch/hydration.spec.js +++ b/test/unit/modules/vdom/patch/hydration.spec.js @@ -388,4 +388,18 @@ describe('vdom patch: hydration', () => { expect(dom.children[0].className).toBe('bar') }).then(done) }) + + // #11109 + it('should not warn failed hydration when there are some empty text vnode in children', () => { + const dom = createMockSSRDOM('
bar
') + + new Vue({ + data: { + a: '' + }, + template: `
bar{{a}}
` + }).$mount(dom) + + expect('not matching server-rendered content').not.toHaveBeenWarned() + }) }) From b79447a379af09e05469dac5a80d839de7f0e8d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=90=E7=AB=A5?= <294437759@qq.com> Date: Sat, 15 Feb 2020 19:38:56 -0600 Subject: [PATCH 2/3] Update test/unit/modules/vdom/patch/hydration.spec.js Co-Authored-By: Eduardo San Martin Morote --- test/unit/modules/vdom/patch/hydration.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/modules/vdom/patch/hydration.spec.js b/test/unit/modules/vdom/patch/hydration.spec.js index 1fb22d969a9..9325956be72 100644 --- a/test/unit/modules/vdom/patch/hydration.spec.js +++ b/test/unit/modules/vdom/patch/hydration.spec.js @@ -390,7 +390,7 @@ describe('vdom patch: hydration', () => { }) // #11109 - it('should not warn failed hydration when there are some empty text vnode in children', () => { + it('should not fail hydration with empty text vnodes children', () => { const dom = createMockSSRDOM('
bar
') new Vue({ From fbb96fd1343b514f840c31b2ec06d39dea87268c Mon Sep 17 00:00:00 2001 From: huanghaoqun Date: Sun, 16 Feb 2020 11:26:44 +0800 Subject: [PATCH 3/3] fix(ssr): ignore empty text vnode but create a empty textNode for next patch when hydrating --- src/core/vdom/patch.js | 3 ++- test/unit/modules/vdom/patch/hydration.spec.js | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/core/vdom/patch.js b/src/core/vdom/patch.js index 92d6d307227..c8f897bee2f 100644 --- a/src/core/vdom/patch.js +++ b/src/core/vdom/patch.js @@ -645,8 +645,9 @@ export function createPatchFunction (backend) { let childNode = elm.firstChild for (let i = 0; i < children.length; i++) { const child = children[i] - // ignore empty text vnode + // ignore empty text vnode but create a empty textNode for next patch if (isUndef(child.tag) && isFalse(child.isComment) && child.text === '') { + createElm(child, insertedVnodeQueue, elm, childNode) continue } if (!childNode || !hydrate(childNode, child, insertedVnodeQueue, inVPre)) { diff --git a/test/unit/modules/vdom/patch/hydration.spec.js b/test/unit/modules/vdom/patch/hydration.spec.js index 9325956be72..1037b8a4f88 100644 --- a/test/unit/modules/vdom/patch/hydration.spec.js +++ b/test/unit/modules/vdom/patch/hydration.spec.js @@ -390,10 +390,10 @@ describe('vdom patch: hydration', () => { }) // #11109 - it('should not fail hydration with empty text vnodes children', () => { + it('should not fail hydration with empty text vnodes children', done => { const dom = createMockSSRDOM('
bar
') - new Vue({ + const vm = new Vue({ data: { a: '' }, @@ -401,5 +401,11 @@ describe('vdom patch: hydration', () => { }).$mount(dom) expect('not matching server-rendered content').not.toHaveBeenWarned() + + // should update + vm.a = 'foo' + waitForUpdate(() => { + expect(dom.children[0].innerHTML).toBe('barfoo') + }).then(done) }) })