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 {
|
import {
|
||||||
|
type ComponentInternalInstance,
|
||||||
type ComponentOptions,
|
type ComponentOptions,
|
||||||
type ConcreteComponent,
|
type ConcreteComponent,
|
||||||
type GenericComponentInstance,
|
type GenericComponentInstance,
|
||||||
|
@ -46,7 +47,7 @@ import { setTransitionHooks } from './BaseTransition'
|
||||||
import type { ComponentRenderContext } from '../componentPublicInstance'
|
import type { ComponentRenderContext } from '../componentPublicInstance'
|
||||||
import { devtoolsComponentAdded } from '../devtools'
|
import { devtoolsComponentAdded } from '../devtools'
|
||||||
import { isAsyncWrapper } from '../apiAsyncComponent'
|
import { isAsyncWrapper } from '../apiAsyncComponent'
|
||||||
import { isSuspense } from './Suspense'
|
import { type SuspenseBoundary, isSuspense } from './Suspense'
|
||||||
import { LifecycleHooks } from '../enums'
|
import { LifecycleHooks } from '../enums'
|
||||||
|
|
||||||
type MatchPattern = string | RegExp | (string | RegExp)[]
|
type MatchPattern = string | RegExp | (string | RegExp)[]
|
||||||
|
@ -118,14 +119,11 @@ const KeepAliveImpl: ComponentOptions = {
|
||||||
|
|
||||||
const parentSuspense = keepAliveInstance.suspense
|
const parentSuspense = keepAliveInstance.suspense
|
||||||
|
|
||||||
|
const { renderer } = sharedContext
|
||||||
const {
|
const {
|
||||||
renderer: {
|
|
||||||
p: patch,
|
|
||||||
m: move,
|
|
||||||
um: _unmount,
|
um: _unmount,
|
||||||
o: { createElement },
|
o: { createElement },
|
||||||
},
|
} = renderer
|
||||||
} = sharedContext
|
|
||||||
const storageContainer = createElement('div')
|
const storageContainer = createElement('div')
|
||||||
|
|
||||||
sharedContext.activate = (
|
sharedContext.activate = (
|
||||||
|
@ -135,72 +133,26 @@ const KeepAliveImpl: ComponentOptions = {
|
||||||
namespace,
|
namespace,
|
||||||
optimized,
|
optimized,
|
||||||
) => {
|
) => {
|
||||||
const instance = vnode.component!
|
activate(
|
||||||
move(
|
|
||||||
vnode,
|
vnode,
|
||||||
container,
|
container,
|
||||||
anchor,
|
anchor,
|
||||||
MoveType.ENTER,
|
renderer,
|
||||||
keepAliveInstance,
|
keepAliveInstance,
|
||||||
parentSuspense,
|
parentSuspense,
|
||||||
)
|
|
||||||
// in case props have changed
|
|
||||||
patch(
|
|
||||||
instance.vnode,
|
|
||||||
vnode,
|
|
||||||
container,
|
|
||||||
anchor,
|
|
||||||
instance,
|
|
||||||
parentSuspense,
|
|
||||||
namespace,
|
namespace,
|
||||||
vnode.slotScopeIds,
|
|
||||||
optimized,
|
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) => {
|
sharedContext.deactivate = (vnode: VNode) => {
|
||||||
const instance = vnode.component!
|
deactivate(
|
||||||
invalidateMount(instance.m)
|
|
||||||
invalidateMount(instance.a)
|
|
||||||
|
|
||||||
move(
|
|
||||||
vnode,
|
vnode,
|
||||||
storageContainer,
|
storageContainer,
|
||||||
null,
|
renderer,
|
||||||
MoveType.LEAVE,
|
|
||||||
keepAliveInstance,
|
keepAliveInstance,
|
||||||
parentSuspense,
|
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) {
|
function unmount(vnode: VNode) {
|
||||||
|
@ -487,3 +439,86 @@ export function resetShapeFlag(vnode: any): void {
|
||||||
function getInnerChild(vnode: VNode) {
|
function getInnerChild(vnode: VNode) {
|
||||||
return vnode.shapeFlag & ShapeFlags.SUSPENSE ? vnode.ssContent! : 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
|
* @internal
|
||||||
*/
|
*/
|
||||||
export { matches, isKeepAlive, resetShapeFlag } from './components/KeepAlive'
|
export {
|
||||||
|
matches,
|
||||||
|
isKeepAlive,
|
||||||
|
resetShapeFlag,
|
||||||
|
activate,
|
||||||
|
deactivate,
|
||||||
|
} from './components/KeepAlive'
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -31,15 +31,16 @@ import { createElement } from '../dom/node'
|
||||||
|
|
||||||
export interface KeepAliveInstance extends VaporComponentInstance {
|
export interface KeepAliveInstance extends VaporComponentInstance {
|
||||||
activate: (
|
activate: (
|
||||||
block: VaporComponentInstance | VaporFragment,
|
instance: VaporComponentInstance,
|
||||||
parentNode: ParentNode,
|
parentNode: ParentNode,
|
||||||
anchor?: Node | null | 0,
|
anchor?: Node | null | 0,
|
||||||
) => void
|
) => void
|
||||||
deactivate: (block: VaporComponentInstance | VaporFragment) => void
|
deactivate: (instance: VaporComponentInstance) => void
|
||||||
process: (block: Block) => void
|
process: (block: Block) => void
|
||||||
getCachedComponent: (
|
getCachedComponent: (
|
||||||
comp: VaporComponent,
|
comp: VaporComponent,
|
||||||
) => VaporComponentInstance | VaporFragment | undefined
|
) => VaporComponentInstance | VaporFragment | undefined
|
||||||
|
getStorageContainer: () => ParentNode
|
||||||
}
|
}
|
||||||
|
|
||||||
type CacheKey = VaporComponent
|
type CacheKey = VaporComponent
|
||||||
|
@ -128,6 +129,7 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
keepAliveInstance.getStorageContainer = () => storageContainer
|
||||||
keepAliveInstance.getCachedComponent = comp => cache.get(comp)
|
keepAliveInstance.getCachedComponent = comp => cache.get(comp)
|
||||||
|
|
||||||
const process = (keepAliveInstance.process = block => {
|
const process = (keepAliveInstance.process = block => {
|
||||||
|
@ -143,18 +145,9 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
keepAliveInstance.activate = (block, parentNode, anchor) => {
|
keepAliveInstance.activate = (instance, parentNode, anchor) => {
|
||||||
current = block
|
current = instance
|
||||||
let instance
|
insert(instance.block, parentNode, anchor)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
queuePostFlushCb(() => {
|
queuePostFlushCb(() => {
|
||||||
instance.isDeactivated = false
|
instance.isDeactivated = false
|
||||||
|
@ -166,17 +159,8 @@ export const VaporKeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keepAliveInstance.deactivate = block => {
|
keepAliveInstance.deactivate = instance => {
|
||||||
let instance
|
insert(instance.block, storageContainer)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
queuePostFlushCb(() => {
|
queuePostFlushCb(() => {
|
||||||
if (instance.da) invokeArrayFns(instance.da)
|
if (instance.da) invokeArrayFns(instance.da)
|
||||||
|
|
|
@ -9,8 +9,10 @@ import {
|
||||||
type Slots,
|
type Slots,
|
||||||
type VNode,
|
type VNode,
|
||||||
type VaporInteropInterface,
|
type VaporInteropInterface,
|
||||||
|
activate,
|
||||||
createVNode,
|
createVNode,
|
||||||
currentInstance,
|
currentInstance,
|
||||||
|
deactivate,
|
||||||
ensureRenderer,
|
ensureRenderer,
|
||||||
onScopeDispose,
|
onScopeDispose,
|
||||||
renderSlot,
|
renderSlot,
|
||||||
|
@ -174,7 +176,13 @@ function createVDOMComponent(
|
||||||
const parentInstance = currentInstance as VaporComponentInstance
|
const parentInstance = currentInstance as VaporComponentInstance
|
||||||
const unmount = (parentNode?: ParentNode) => {
|
const unmount = (parentNode?: ParentNode) => {
|
||||||
if (vnode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {
|
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
|
return
|
||||||
}
|
}
|
||||||
internals.umt(vnode.component!, null, !!parentNode)
|
internals.umt(vnode.component!, null, !!parentNode)
|
||||||
|
@ -182,7 +190,16 @@ function createVDOMComponent(
|
||||||
|
|
||||||
frag.insert = (parentNode, anchor) => {
|
frag.insert = (parentNode, anchor) => {
|
||||||
if (vnode.shapeFlag & ShapeFlags.COMPONENT_KEPT_ALIVE) {
|
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
|
return
|
||||||
}
|
}
|
||||||
if (!isMounted) {
|
if (!isMounted) {
|
||||||
|
|
Loading…
Reference in New Issue