Skip to content

Commit 61f339c

Browse files
ubugeeeisxzz
andauthored
feat: vapor component base (#5)
Co-authored-by: 三咲智子 Kevin Deng <sxzz@sxzz.moe>
1 parent da931ea commit 61f339c

File tree

2 files changed

+68
-11
lines changed

2 files changed

+68
-11
lines changed
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { EffectScope } from '@vue/reactivity'
2+
3+
import { Block, BlockFn } from './render'
4+
5+
export interface ComponentInternalInstance {
6+
uid: number
7+
container: ParentNode
8+
block: Block | null
9+
scope: EffectScope
10+
11+
component: BlockFn
12+
isMounted: boolean
13+
14+
// TODO: registory of provides, appContext, lifecycles, ...
15+
}
16+
17+
let uid = 0
18+
export const createComponentInstance = (
19+
component: BlockFn
20+
): ComponentInternalInstance => {
21+
const instance: ComponentInternalInstance = {
22+
uid: uid++,
23+
block: null,
24+
container: null!, // set on mount
25+
scope: new EffectScope(true /* detached */)!,
26+
27+
component,
28+
isMounted: false
29+
// TODO: registory of provides, appContext, lifecycles, ...
30+
}
31+
return instance
32+
}
33+
34+
// FIXME: duplicated with runtime-core
35+
export type Data = Record<string, unknown>

packages/runtime-vapor/src/render.ts

+33-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import {
2+
isArray,
23
normalizeClass,
34
normalizeStyle,
4-
toDisplayString,
5-
isArray
5+
toDisplayString
66
} from '@vue/shared'
7-
import { effectScope } from '@vue/reactivity'
7+
8+
import { ComponentInternalInstance, createComponentInstance } from './component'
89

910
export type Block = Node | Fragment | Block[]
1011
export type ParentBlock = ParentNode | Node[]
@@ -14,14 +15,10 @@ export type BlockFn = (props?: any) => Block
1415
export function render(
1516
comp: BlockFn,
1617
container: string | ParentNode
17-
): () => void {
18-
const scope = effectScope()
19-
const block = scope.run(() => comp())!
20-
insert(block, (container = normalizeContainer(container)))
21-
return () => {
22-
scope.stop()
23-
remove(block, container as ParentNode)
24-
}
18+
): ComponentInternalInstance {
19+
const instance = createComponentInstance(comp)
20+
mountComponent(instance, (container = normalizeContainer(container)))
21+
return instance
2522
}
2623

2724
export function normalizeContainer(container: string | ParentNode): ParentNode {
@@ -30,6 +27,31 @@ export function normalizeContainer(container: string | ParentNode): ParentNode {
3027
: container
3128
}
3229

30+
export const mountComponent = (
31+
instance: ComponentInternalInstance,
32+
container: ParentNode
33+
) => {
34+
instance.container = container
35+
const block = instance.scope.run(
36+
() => (instance.block = instance.component())
37+
)!
38+
insert(block, instance.container)
39+
instance.isMounted = true
40+
// TODO: lifecycle hooks (mounted, ...)
41+
// const { m } = instance
42+
// m && invoke(m)
43+
}
44+
45+
export const unmountComponent = (instance: ComponentInternalInstance) => {
46+
const { container, block, scope } = instance
47+
scope.stop()
48+
block && remove(block, container)
49+
instance.isMounted = false
50+
// TODO: lifecycle hooks (unmounted, ...)
51+
// const { um } = instance
52+
// um && invoke(um)
53+
}
54+
3355
export function insert(
3456
block: Block,
3557
parent: ParentNode,

0 commit comments

Comments
 (0)