mirror of https://github.com/vuejs/core.git
wip: vdom interop
This commit is contained in:
parent
6c4d22ac73
commit
eeb6ab886a
|
@ -1,4 +1,5 @@
|
|||
import {
|
||||
type ComponentInternalInstance,
|
||||
type ComponentOptions,
|
||||
type ConcreteComponent,
|
||||
type GenericComponentInstance,
|
||||
|
@ -46,7 +47,7 @@ import { setTransitionHooks } from './BaseTransition'
|
|||
import type { ComponentRenderContext } from '../componentPublicInstance'
|
||||
import { devtoolsComponentAdded } from '../devtools'
|
||||
import { isAsyncWrapper } from '../apiAsyncComponent'
|
||||
import { isSuspense } from './Suspense'
|
||||
import { type SuspenseBoundary, isSuspense } from './Suspense'
|
||||
import { LifecycleHooks } from '../enums'
|
||||
|
||||
type MatchPattern = string | RegExp | (string | RegExp)[]
|
||||
|
@ -118,14 +119,11 @@ const KeepAliveImpl: ComponentOptions = {
|
|||
|
||||
const parentSuspense = keepAliveInstance.suspense
|
||||
|
||||
const { renderer } = sharedContext
|
||||
const {
|
||||
renderer: {
|
||||
p: patch,
|
||||
m: move,
|
||||
um: _unmount,
|
||||
o: { createElement },
|
||||
},
|
||||
} = sharedContext
|
||||
um: _unmount,
|
||||
o: { createElement },
|
||||
} = renderer
|
||||
const storageContainer = createElement('div')
|
||||
|
||||
sharedContext.activate = (
|
||||
|
@ -135,72 +133,26 @@ const KeepAliveImpl: ComponentOptions = {
|
|||
namespace,
|
||||
optimized,
|
||||
) => {
|
||||
const instance = vnode.component!
|
||||
move(
|
||||
activate(
|
||||
vnode,
|
||||
container,
|
||||
anchor,
|
||||
MoveType.ENTER,
|
||||
renderer,
|
||||
keepAliveInstance,
|
||||
parentSuspense,
|
||||
)
|
||||
// in case props have changed
|
||||
patch(
|
||||
instance.vnode,
|
||||
vnode,
|
||||
container,
|
||||
anchor,
|
||||
instance,
|
||||
parentSuspense,
|
||||
namespace,
|
||||
vnode.slotScopeIds,
|
||||
optimized,
|
||||
)
|
||||
queuePostRenderEffect(() => {
|
||||
instance.isDeactivated = false
|
||||
if (instance.a) {
|
||||
invokeArrayFns(instance.a)
|
||||
}
|
||||
const vnodeHook = vnode.props && vnode.props.onVnodeMounted
|
||||
if (vnodeHook) {
|
||||
invokeVNodeHook(vnodeHook, instance.parent, vnode)
|
||||
}
|
||||
}, parentSuspense)
|
||||
|
||||
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
|
||||
// Update components tree
|
||||
devtoolsComponentAdded(instance)
|
||||
}
|
||||
}
|
||||
|
||||
sharedContext.deactivate = (vnode: VNode) => {
|
||||
const instance = vnode.component!
|
||||
invalidateMount(instance.m)
|
||||
invalidateMount(instance.a)
|
||||
|
||||
move(
|
||||
deactivate(
|
||||
vnode,
|
||||
storageContainer,
|
||||
null,
|
||||
MoveType.LEAVE,
|
||||
renderer,
|
||||
keepAliveInstance,
|
||||
parentSuspense,
|
||||
)
|
||||
queuePostRenderEffect(() => {
|
||||
if (instance.da) {
|
||||
invokeArrayFns(instance.da)
|
||||
}
|
||||
const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted
|
||||
if (vnodeHook) {
|
||||
invokeVNodeHook(vnodeHook, instance.parent, vnode)
|
||||
}
|
||||
instance.isDeactivated = true
|
||||
}, parentSuspense)
|
||||
|
||||
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
|
||||
// Update components tree
|
||||
devtoolsComponentAdded(instance)
|
||||
}
|
||||
}
|
||||
|
||||
function unmount(vnode: VNode) {
|
||||
|
@ -487,3 +439,86 @@ export function resetShapeFlag(vnode: any): void {
|
|||
function getInnerChild(vnode: VNode) {
|
||||
return vnode.shapeFlag & ShapeFlags.SUSPENSE ? vnode.ssContent! : vnode
|
||||
}
|
||||
|
||||
/**
|
||||
* shared between runtime-core and runtime-vapor
|
||||
*/
|
||||
export function activate(
|
||||
vnode: VNode,
|
||||
container: RendererElement,
|
||||
anchor: RendererNode | null,
|
||||
{ p: patch, m: move }: RendererInternals,
|
||||
parentComponent: ComponentInternalInstance | null,
|
||||
parentSuspense: SuspenseBoundary | null,
|
||||
namespace?: ElementNamespace,
|
||||
optimized?: boolean,
|
||||
): void {
|
||||
const instance = vnode.component!
|
||||
move(
|
||||
vnode,
|
||||
container,
|
||||
anchor,
|
||||
MoveType.ENTER,
|
||||
parentComponent,
|
||||
parentSuspense,
|
||||
)
|
||||
// in case props have changed
|
||||
patch(
|
||||
instance.vnode,
|
||||
vnode,
|
||||
container,
|
||||
anchor,
|
||||
instance,
|
||||
parentSuspense,
|
||||
namespace,
|
||||
vnode.slotScopeIds,
|
||||
optimized,
|
||||
)
|
||||
queuePostRenderEffect(() => {
|
||||
instance.isDeactivated = false
|
||||
if (instance.a) {
|
||||
invokeArrayFns(instance.a)
|
||||
}
|
||||
const vnodeHook = vnode.props && vnode.props.onVnodeMounted
|
||||
if (vnodeHook) {
|
||||
invokeVNodeHook(vnodeHook, instance.parent, vnode)
|
||||
}
|
||||
}, parentSuspense)
|
||||
|
||||
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
|
||||
// Update components tree
|
||||
devtoolsComponentAdded(instance)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shared between runtime-core and runtime-vapor
|
||||
*/
|
||||
export function deactivate(
|
||||
vnode: VNode,
|
||||
container: RendererElement,
|
||||
{ m: move }: RendererInternals,
|
||||
parentComponent: ComponentInternalInstance | null,
|
||||
parentSuspense: SuspenseBoundary | null,
|
||||
): void {
|
||||
const instance = vnode.component!
|
||||
invalidateMount(instance.m)
|
||||
invalidateMount(instance.a)
|
||||
|
||||
move(vnode, container, null, MoveType.LEAVE, parentComponent, parentSuspense)
|
||||
queuePostRenderEffect(() => {
|
||||
if (instance.da) {
|
||||
invokeArrayFns(instance.da)
|
||||
}
|
||||
const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted
|
||||
if (vnodeHook) {
|
||||
invokeVNodeHook(vnodeHook, instance.parent, vnode)
|
||||
}
|
||||
instance.isDeactivated = true
|
||||
}, parentSuspense)
|
||||
|
||||
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
|
||||
// Update components tree
|
||||
devtoolsComponentAdded(instance)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -564,7 +564,13 @@ export { getComponentName } from './component'
|
|||
/**
|
||||
* @internal
|
||||
*/
|
||||
export { matches, isKeepAlive, resetShapeFlag } from './components/KeepAlive'
|
||||
export {
|
||||
matches,
|
||||
isKeepAlive,
|
||||
resetShapeFlag,
|
||||
activate,
|
||||
deactivate,
|
||||
} from './components/KeepAlive'
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -31,15 +31,16 @@ import { createElement } from '../dom/node'
|
|||
|
||||
export interface KeepAliveInstance extends VaporComponentInstance {
|
||||
activate: (
|
||||
block: VaporComponentInstance | VaporFragment,
|
||||
instance: VaporComponentInstance,
|
||||
parentNode: ParentNode,
|
||||
anchor?: Node | null | 0,
|
||||
) => void
|
||||
deactivate: (block: VaporComponentInstance | VaporFragment) => void
|
||||
deactivate: (instance: VaporComponentInstance) => void
|
||||
process: (block: Block) => void
|
||||
getCachedComponent: (
|
||||
comp: VaporComponent,
|
||||
) => VaporComponentInstance | VaporFragment | undefined
|
||||
getStorageContainer: () => ParentNode
|
||||
}
|
||||
|
||||
type CacheKey = VaporComponent
|
||||
|
@ -128,6 +129,7 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
|||
})
|
||||
})
|
||||
|
||||
keepAliveInstance.getStorageContainer = () => storageContainer
|
||||
keepAliveInstance.getCachedComponent = comp => cache.get(comp)
|
||||
|
||||
const process = (keepAliveInstance.process = block => {
|
||||
|
@ -143,18 +145,9 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
|||
}
|
||||
})
|
||||
|
||||
keepAliveInstance.activate = (block, parentNode, anchor) => {
|
||||
current = block
|
||||
let instance
|
||||
if (isVaporComponent(block)) {
|
||||
instance = block
|
||||
insert(block.block, parentNode, anchor)
|
||||
} else {
|
||||
// vdom interop
|
||||
const comp = block.nodes as any
|
||||
insert(comp.el, parentNode, anchor)
|
||||
instance = comp.component
|
||||
}
|
||||
keepAliveInstance.activate = (instance, parentNode, anchor) => {
|
||||
current = instance
|
||||
insert(instance.block, parentNode, anchor)
|
||||
|
||||
queuePostFlushCb(() => {
|
||||
instance.isDeactivated = false
|
||||
|
@ -166,17 +159,8 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
|||
}
|
||||
}
|
||||
|
||||
keepAliveInstance.deactivate = block => {
|
||||
let instance
|
||||
if (isVaporComponent(block)) {
|
||||
instance = block
|
||||
insert(block.block, storageContainer)
|
||||
} else {
|
||||
// vdom interop
|
||||
const comp = block.nodes as any
|
||||
insert(comp.el, storageContainer)
|
||||
instance = comp.component
|
||||
}
|
||||
keepAliveInstance.deactivate = instance => {
|
||||
insert(instance.block, storageContainer)
|
||||
|
||||
queuePostFlushCb(() => {
|
||||
if (instance.da) invokeArrayFns(instance.da)
|
||||
|
|
|
@ -9,8 +9,10 @@ import {
|
|||
type Slots,
|
||||
type VNode,
|
||||
type VaporInteropInterface,
|
||||
activate,
|
||||
createVNode,
|
||||
currentInstance,
|
||||
deactivate,
|
||||
ensureRenderer,
|
||||
onScopeDispose,
|
||||
renderSlot,
|
||||
|
@ -174,7 +176,13 @@ function createVDOMComponent(
|
|||
const parentInstance = currentInstance as VaporComponentInstance
|
||||
const unmount = (parentNode?: ParentNode) => {
|
||||
if (vnode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {
|
||||
;(parentInstance as KeepAliveInstance).deactivate(frag)
|
||||
deactivate(
|
||||
vnode,
|
||||
(parentInstance as KeepAliveInstance).getStorageContainer(),
|
||||
internals,
|
||||
parentInstance as any,
|
||||
null,
|
||||
)
|
||||
return
|
||||
}
|
||||
internals.umt(vnode.component!, null, !!parentNode)
|
||||
|
@ -182,7 +190,16 @@ function createVDOMComponent(
|
|||
|
||||
frag.insert = (parentNode, anchor) => {
|
||||
if (vnode.shapeFlag & ShapeFlags.COMPONENT_KEPT_ALIVE) {
|
||||
;(parentInstance as KeepAliveInstance).activate(frag, parentNode, anchor)
|
||||
activate(
|
||||
vnode,
|
||||
parentNode,
|
||||
anchor,
|
||||
internals,
|
||||
parentInstance as any,
|
||||
null,
|
||||
undefined,
|
||||
false,
|
||||
)
|
||||
return
|
||||
}
|
||||
if (!isMounted) {
|
||||
|
|
Loading…
Reference in New Issue