From cb67ffe4429ebfbdf42b5d18e1e1b168109d472e Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 5 Jun 2016 16:14:51 -0400 Subject: [PATCH] ensure abstract HOCs do not alter parent chain --- flow/component.js | 1 + src/core/components/keep-alive.js | 2 ++ src/core/instance/lifecycle.js | 4 ++-- src/core/instance/render.js | 17 +++++++++++++++-- src/core/util/env.js | 2 +- src/core/vdom/create-element.js | 2 +- .../runtime/components/transition-control.js | 2 ++ 7 files changed, 24 insertions(+), 6 deletions(-) diff --git a/flow/component.js b/flow/component.js index 7debfac1..7ee8d293 100644 --- a/flow/component.js +++ b/flow/component.js @@ -47,6 +47,7 @@ declare interface Component { _isVue: true; _self: Component; _renderProxy: Component; + _renderParent: ?Component; _watcher: Watcher; _watchers: Array; _data: Object; diff --git a/src/core/components/keep-alive.js b/src/core/components/keep-alive.js index 33d9895a..aba7d6c0 100644 --- a/src/core/components/keep-alive.js +++ b/src/core/components/keep-alive.js @@ -1,4 +1,6 @@ export default { + name: 'keep-alive', + _abstract: true, created () { this.cache = Object.create(null) }, diff --git a/src/core/instance/lifecycle.js b/src/core/instance/lifecycle.js index 691caa5a..72178a5e 100644 --- a/src/core/instance/lifecycle.js +++ b/src/core/instance/lifecycle.js @@ -10,7 +10,7 @@ export function initLifecycle (vm: Component) { vm.$parent = options.parent vm.$root = vm.$parent ? vm.$parent.$root : vm - if (vm.$parent) { + if (vm.$parent && !options._abstract) { vm.$parent.$children.push(vm) } @@ -145,7 +145,7 @@ export function lifecycleMixin (Vue: Class) { vm._isBeingDestroyed = true // remove self from parent const parent = vm.$parent - if (parent && !parent._isBeingDestroyed) { + if (parent && !parent._isBeingDestroyed && !vm.$options._abstract) { remove(parent.$children, vm) } // teardown watchers diff --git a/src/core/instance/render.js b/src/core/instance/render.js index 1e3f320b..7f22eb8b 100644 --- a/src/core/instance/render.js +++ b/src/core/instance/render.js @@ -16,7 +16,7 @@ import { } from '../vdom/create-element' export const renderState: { - activeInstance: Component | null + activeInstance: ?Component } = { activeInstance: null } @@ -35,6 +35,19 @@ export function initRender (vm: Component) { ) { return this._h(this._e(tag, data, namespace), children) }, vm) + // for abstract components, determine first non-abstract parent + // so that the children of abstract components are considered children + // of the first non-abstract parent. + // this is used by internal abstract components like . + if (vm.$options._abstract) { + let parent = vm.$parent + while (parent && parent.$options._abstract) { + parent = parent.$parent + } + vm._renderParent = parent + } else { + vm._renderParent = vm + } if (vm.$options.el) { vm.$mount(vm.$options.el) } @@ -48,7 +61,7 @@ export function renderMixin (Vue: Class) { Vue.prototype._render = function (): VNode { const vm: Component = this const prev = renderState.activeInstance - renderState.activeInstance = vm + renderState.activeInstance = vm._renderParent if (!vm._isMounted) { // render static sub-trees for once on initial render renderStaticTrees(vm) diff --git a/src/core/util/env.js b/src/cor