From 0b16927c9d382b9cf134b131b898350340c2ee41 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Thu, 25 Oct 2018 01:26:20 +0800 Subject: [PATCH] fix(transition): check existence of `el.parentNode` (#8422) fix #8199 * fix(transition): check existence of `el.parentNode` If the new parentNode gets a `textContent` or `innerHTML` property during patching, the `transition` node would have been detached early, which means `el.parentNode` no longer exists. * fix(vdom): should not reuse nodes with `textContent` / `innerHTML` props --- src/core/vdom/patch.js | 7 ++++++ .../web/runtime/modules/transition.js | 2 +- .../features/transition/transition.spec.js | 22 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/core/vdom/patch.js b/src/core/vdom/patch.js index 676499dc69e..81289f01521 100644 --- a/src/core/vdom/patch.js +++ b/src/core/vdom/patch.js @@ -32,6 +32,12 @@ export const emptyNode = new VNode('', {}, []) const hooks = ['create', 'activate', 'update', 'remove', 'destroy'] +function childrenIgnored (vnode) { + return vnode && vnode.data && vnode.data.domProps && ( + vnode.data.domProps.innerHTML || vnode.data.domProps.textContent + ) +} + function sameVnode (a, b) { return ( a.key === b.key && ( @@ -39,6 +45,7 @@ function sameVnode (a, b) { a.tag === b.tag && a.isComment === b.isComment && isDef(a.data) === isDef(b.data) && + !childrenIgnored(a) && !childrenIgnored(b) && sameInputType(a, b) ) || ( isTrue(a.isAsyncPlaceholder) && diff --git a/src/platforms/web/runtime/modules/transition.js b/src/platforms/web/runtime/modules/transition.js index 0796b5dad5e..128a1c0bd1b 100644 --- a/src/platforms/web/runtime/modules/transition.js +++ b/src/platforms/web/runtime/modules/transition.js @@ -251,7 +251,7 @@ export function leave (vnode: VNodeWithData, rm: Function) { return } // record leaving element - if (!vnode.data.show) { + if (!vnode.data.show && el.parentNode) { (el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key: any)] = vnode } beforeLeave && beforeLeave(el) diff --git a/test/unit/features/transition/transition.spec.js b/test/unit/features/transition/transition.spec.js index f7b08e376a5..2ecf80b854d 100644 --- a/test/unit/features/transition/transition.spec.js +++ b/test/unit/features/transition/transition.spec.js @@ -1167,5 +1167,27 @@ if (!isIE9) { expect(vm.$el.innerHTML).toBe('') }).then(done) }) + + // #8199 + it('should not throw error when replaced by v-html contents', (done) => { + const vm = new Vue({ + template: ` +
+
+ + a + +
+
+
+ `, + data: { ok: true } + }).$mount(el) + + vm.ok = false + waitForUpdate(() => { + expect(vm.$el.children[0].innerHTML).toBe('false') + }).then(done) + }) }) }