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 {
|
import {
|
||||||
|
isArray,
|
||||||
normalizeClass,
|
normalizeClass,
|
||||||
normalizeStyle,
|
normalizeStyle,
|
||||||
toDisplayString,
|
toDisplayString
|
||||||
isArray
|
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import { effectScope } from '@vue/reactivity'
|
|
||||||
|
import { ComponentInternalInstance, createComponentInstance } from './component'
|
||||||
|
|
||||||
export type Block = Node | Fragment | Block[]
|
export type Block = Node | Fragment | Block[]
|
||||||
export type ParentBlock = ParentNode | Node[]
|
export type ParentBlock = ParentNode | Node[]
|
||||||
|
@ -14,14 +15,10 @@ export type BlockFn = (props?: any) => Block
|
||||||
export function render(
|
export function render(
|
||||||
comp: BlockFn,
|
comp: BlockFn,
|
||||||
container: string | ParentNode
|
container: string | ParentNode
|
||||||
): () => void {
|
): ComponentInternalInstance {
|
||||||
const scope = effectScope()
|
const instance = createComponentInstance(comp)
|
||||||
const block = scope.run(() => comp())!
|
mountComponent(instance, (container = normalizeContainer(container)))
|
||||||
insert(block, (container = normalizeContainer(container)))
|
return instance
|
||||||
return () => {
|
|
||||||
scope.stop()
|
|
||||||
remove(block, container as ParentNode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizeContainer(container: string | ParentNode): ParentNode {
|
export function normalizeContainer(container: string | ParentNode): ParentNode {
|
||||||
|
@ -30,6 +27,31 @@ export function normalizeContainer(container: string | ParentNode): ParentNode {
|
||||||
: container
|
: 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(
|
export function insert(
|
||||||
block: Block,
|
block: Block,
|
||||||
parent: ParentNode,
|
parent: ParentNode,
|
||||||
|
|
Loading…
Reference in New Issue