feat: vapor component base (#5)

Co-authored-by: 三咲智子 Kevin Deng <sxzz@sxzz.moe>
This commit is contained in:
ubugeeei 2023-11-30 03:11:21 +09:00 committed by GitHub
parent da931ea942
commit 61f339ce7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 11 deletions

View File

@ -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>

View File

@ -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,