|
@@ -26,6 +26,7 @@ import {
|
|
|
normalizeComponentRoot,
|
|
normalizeComponentRoot,
|
|
|
shouldUpdateFunctionalComponent
|
|
shouldUpdateFunctionalComponent
|
|
|
} from './componentUtils'
|
|
} from './componentUtils'
|
|
|
|
|
+import { KeepAliveSymbol } from './optional/keepAlive'
|
|
|
|
|
|
|
|
interface NodeOps {
|
|
interface NodeOps {
|
|
|
createElement: (tag: string, isSVG?: boolean) => any
|
|
createElement: (tag: string, isSVG?: boolean) => any
|
|
@@ -271,15 +272,22 @@ export function createRenderer(options: RendererOptions) {
|
|
|
let el: RenderNode | RenderFragment
|
|
let el: RenderNode | RenderFragment
|
|
|
const { flags, tag, data, slots } = vnode
|
|
const { flags, tag, data, slots } = vnode
|
|
|
if (flags & VNodeFlags.COMPONENT_STATEFUL) {
|
|
if (flags & VNodeFlags.COMPONENT_STATEFUL) {
|
|
|
- el = mountComponentInstance(
|
|
|
|
|
- vnode,
|
|
|
|
|
- tag as ComponentClass,
|
|
|
|
|
- null,
|
|
|
|
|
- parentComponent,
|
|
|
|
|
- isSVG,
|
|
|
|
|
- endNode
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ if (flags & VNodeFlags.COMPONENT_STATEFUL_KEPT_ALIVE) {
|
|
|
|
|
+ // kept-alive
|
|
|
|
|
+ el = vnode.el as RenderNode
|
|
|
|
|
+ // TODO activated hook
|
|
|
|
|
+ } else {
|
|
|
|
|
+ el = mountComponentInstance(
|
|
|
|
|
+ vnode,
|
|
|
|
|
+ tag as ComponentClass,
|
|
|
|
|
+ null,
|
|
|
|
|
+ parentComponent,
|
|
|
|
|
+ isSVG,
|
|
|
|
|
+ endNode
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ debugger
|
|
|
// functional component
|
|
// functional component
|
|
|
const render = tag as FunctionalComponent
|
|
const render = tag as FunctionalComponent
|
|
|
const { props, attrs } = resolveProps(data, render.props, render)
|
|
const { props, attrs } = resolveProps(data, render.props, render)
|
|
@@ -1098,7 +1106,9 @@ export function createRenderer(options: RendererOptions) {
|
|
|
}
|
|
}
|
|
|
} else if (flags & VNodeFlags.COMPONENT) {
|
|
} else if (flags & VNodeFlags.COMPONENT) {
|
|
|
if (flags & VNodeFlags.COMPONENT_STATEFUL) {
|
|
if (flags & VNodeFlags.COMPONENT_STATEFUL) {
|
|
|
- unmountComponentInstance(children as MountedComponent)
|
|
|
|
|
|
|
+ if ((flags & VNodeFlags.COMPONENT_STATEFUL_SHOULD_KEEP_ALIVE) === 0) {
|
|
|
|
|
+ unmountComponentInstance(children as MountedComponent)
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
unmount(children as VNode)
|
|
unmount(children as VNode)
|
|
|
}
|
|
}
|
|
@@ -1161,12 +1171,17 @@ export function createRenderer(options: RendererOptions) {
|
|
|
isSVG: boolean,
|
|
isSVG: boolean,
|
|
|
endNode: RenderNode | RenderFragment | null
|
|
endNode: RenderNode | RenderFragment | null
|
|
|
): RenderNode {
|
|
): RenderNode {
|
|
|
- // a vnode may already have an instance if this is a compat call
|
|
|
|
|
- // with new Vue()
|
|
|
|
|
|
|
+ // a vnode may already have an instance if this is a compat call with
|
|
|
|
|
+ // new Vue()
|
|
|
const instance =
|
|
const instance =
|
|
|
(__COMPAT__ && (parentVNode.children as MountedComponent)) ||
|
|
(__COMPAT__ && (parentVNode.children as MountedComponent)) ||
|
|
|
createComponentInstance(parentVNode, Component, parentComponent)
|
|
createComponentInstance(parentVNode, Component, parentComponent)
|
|
|
|
|
|
|
|
|
|
+ // inject platform-specific unmount to keep-alive container
|
|
|
|
|
+ if ((Component as any)[KeepAliveSymbol] === true) {
|
|
|
|
|
+ ;(instance as any).$unmount = unmountComponentInstance
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (instance.beforeMount) {
|
|
if (instance.beforeMount) {
|
|
|
instance.beforeMount.call(instance.$proxy)
|
|
instance.beforeMount.call(instance.$proxy)
|
|
|
}
|
|
}
|
|
@@ -1177,7 +1192,7 @@ export function createRenderer(options: RendererOptions) {
|
|
|
|
|
|
|
|
instance._updateHandle = autorun(
|
|
instance._updateHandle = autorun(
|
|
|
() => {
|
|
() => {
|
|
|
- if (instance._destroyed) {
|
|
|
|
|
|
|
+ if (instance._unmounted) {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
if (instance._mounted) {
|
|
if (instance._mounted) {
|
|
@@ -1271,6 +1286,9 @@ export function createRenderer(options: RendererOptions) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function unmountComponentInstance(instance: MountedComponent) {
|
|
function unmountComponentInstance(instance: MountedComponent) {
|
|
|
|
|
+ if (instance._unmounted) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
if (instance.beforeUnmount) {
|
|
if (instance.beforeUnmount) {
|
|
|
instance.beforeUnmount.call(instance.$proxy)
|
|
instance.beforeUnmount.call(instance.$proxy)
|
|
|
}
|
|
}
|
|
@@ -1279,7 +1297,7 @@ export function createRenderer(options: RendererOptions) {
|
|
|
}
|
|
}
|
|
|
stop(instance._updateHandle)
|
|
stop(instance._updateHandle)
|
|
|
teardownComponentInstance(instance)
|
|
teardownComponentInstance(instance)
|
|
|
- instance._destroyed = true
|
|
|
|
|
|
|
+ instance._unmounted = true
|
|
|
if (instance.unmounted) {
|
|
if (instance.unmounted) {
|
|
|
instance.unmounted.call(instance.$proxy)
|
|
instance.unmounted.call(instance.$proxy)
|
|
|
}
|
|
}
|