feat: vapor component base (#5)
Co-authored-by: 三咲智子 Kevin Deng <sxzz@sxzz.moe>
This commit is contained in:
parent
da931ea942
commit
61f339ce7d
|
@ -0,0 +1,35 @@
|
|||
import { EffectScope } from '@vue/reactivity'
|
||||
|
||||
import { Block, BlockFn } from './render'
|
||||
|
||||
export interface ComponentInternalInstance {
|
||||
uid: number
|
||||
container: ParentNode
|
||||
block: Block | null
|
||||
scope: EffectScope
|
||||
|
||||
component: BlockFn
|
||||
isMounted: boolean
|
||||
|
||||
// TODO: registory of provides, appContext, lifecycles, ...
|
||||
}
|
||||
|
||||
let uid = 0
|
||||
export const createComponentInstance = (
|
||||
component: BlockFn
|
||||
): ComponentInternalInstance => {
|
||||
const instance: ComponentInternalInstance = {
|
||||
uid: uid++,
|
||||
block: null,
|
||||
container: null!, // set on mount
|
||||
scope: new EffectScope(true /* detached */)!,
|
||||
|
||||
component,
|
||||
isMounted: false
|
||||
// TODO: registory of provides, appContext, lifecycles, ...
|
||||
}
|
||||
return instance
|
||||
}
|
||||
|
||||
// FIXME: duplicated with runtime-core
|
||||
export type Data = Record<string, unknown>
|
|
@ -1,10 +1,11 @@
|
|||
import {
|
||||
isArray,
|
||||
normalizeClass,
|
||||
normalizeStyle,
|
||||
toDisplayString,
|
||||
isArray
|
||||
toDisplayString
|
||||
} from '@vue/shared'
|
||||
import { effectScope } from '@vue/reactivity'
|
||||
|
||||
import { ComponentInternalInstance, createComponentInstance } from './component'
|
||||
|
||||
export type Block = Node | Fragment | Block[]
|
||||
export type ParentBlock = ParentNode | Node[]
|
||||
|
@ -14,14 +15,10 @@ export type BlockFn = (props?: any) => Block
|
|||
export function render(
|
||||
comp: BlockFn,
|
||||
container: string | ParentNode
|
||||
): () => void {
|
||||
const scope = effectScope()
|
||||
const block = scope.run(() => comp())!
|
||||
insert(block, (container = normalizeContainer(container)))
|
||||
return () => {
|
||||
scope.stop()
|
||||
remove(block, container as ParentNode)
|
||||
}
|
||||
): ComponentInternalInstance {
|
||||
const instance = createComponentInstance(comp)
|
||||
mountComponent(instance, (container = normalizeContainer(container)))
|
||||
return instance
|
||||
}
|
||||
|
||||
export function normalizeContainer(container: string | ParentNode): ParentNode {
|
||||
|
@ -30,6 +27,31 @@ export function normalizeContainer(container: string | ParentNode): ParentNode {
|
|||
: container
|
||||
}
|
||||
|
||||
export const mountComponent = (
|
||||
instance: ComponentInternalInstance,
|
||||
container: ParentNode
|
||||
) => {
|
||||
instance.container = container
|
||||
const block = instance.scope.run(
|
||||
() => (instance.block = instance.component())
|
||||
)!
|
||||
insert(block, instance.container)
|
||||
instance.isMounted = true
|
||||
// TODO: lifecycle hooks (mounted, ...)
|
||||
// const { m } = instance
|
||||
// m && invoke(m)
|
||||
}
|
||||
|
||||
export const unmountComponent = (instance: ComponentInternalInstance) => {
|
||||
const { container, block, scope } = instance
|
||||
scope.stop()
|
||||
block && remove(block, container)
|
||||
instance.isMounted = false
|
||||
// TODO: lifecycle hooks (unmounted, ...)
|
||||
// const { um } = instance
|
||||
// um && invoke(um)
|
||||
}
|
||||
|
||||
export function insert(
|
||||
block: Block,
|
||||
parent: ParentNode,
|
||||
|
|
Loading…
Reference in New Issue