Component,
ref,
nextTick,
- Suspense
+ Suspense,
+ KeepAlive
} from '../src'
import { createApp, nodeOps, serializeInner } from '@vue/runtime-test'
+import { onActivated } from '../src/components/KeepAlive'
const timeout = (n: number = 0) => new Promise(r => setTimeout(r, n))
expect(vnodeHooks.onVnodeBeforeUnmount).toHaveBeenCalledTimes(1)
expect(vnodeHooks.onVnodeUnmounted).toHaveBeenCalledTimes(1)
})
+
+ test('with keepalive', async () => {
+ const spy = jest.fn()
+ let resolve: (comp: Component) => void
+
+ const Foo = defineAsyncComponent(
+ () =>
+ new Promise(r => {
+ resolve = r as any
+ })
+ )
+
+ const root = nodeOps.createElement('div')
+ const app = createApp({
+ render: () => h(KeepAlive, [h(Foo)])
+ })
+
+ app.mount(root)
+ await nextTick()
+
+ resolve!({
+ setup() {
+ onActivated(() => {
+ spy()
+ })
+ return () => 'resolved'
+ }
+ })
+
+ await timeout()
+ expect(serializeInner(root)).toBe('resolved')
+ expect(spy).toBeCalledTimes(1)
+ })
+
})
isInSSRComponentSetup,
ComponentOptions
} from './component'
-import { isFunction, isObject } from '@vue/shared'
+import { isFunction, isObject, ShapeFlags } from '@vue/shared'
import { ComponentPublicInstance } from './componentPublicInstance'
import { createVNode, VNode } from './vnode'
import { defineComponent } from './apiDefineComponent'
function createInnerComp(
comp: ConcreteComponent,
- { vnode: { ref, props, children } }: ComponentInternalInstance
+ { vnode: { ref, props, children }, parent }: ComponentInternalInstance
) {
const vnode = createVNode(comp, props, children)
// ensure inner component inherits the async wrapper's ref owner
vnode.ref = ref
+
+ if (parent && isKeepAlive(parent.vnode)) {
+ vnode.shapeFlag |= ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE
+ }
return vnode
}