From e4f87aef0a8efe20e32afd72c0fd9724e4347de9 Mon Sep 17 00:00:00 2001 From: Ubugeeei Date: Mon, 27 Nov 2023 02:06:32 +0900 Subject: [PATCH 1/2] feat: vapor component base --- packages/runtime-vapor/src/component.ts | 35 ++++++++++++++++++++ packages/runtime-vapor/src/render.ts | 44 ++++++++++++++++++------- 2 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 packages/runtime-vapor/src/component.ts diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts new file mode 100644 index 000000000..6381f4ba1 --- /dev/null +++ b/packages/runtime-vapor/src/component.ts @@ -0,0 +1,35 @@ +import { EffectScope } from '@vue/reactivity' + +import { Block, BlockFn } from './render' + +export interface ComponentInternalInstance { + uid: number + container: ParentNode + block: Block + 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!, // set on mount + 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 diff --git a/packages/runtime-vapor/src/render.ts b/packages/runtime-vapor/src/render.ts index 43ce1ad93..3bf7e5acd 100644 --- a/packages/runtime-vapor/src/render.ts +++ b/packages/runtime-vapor/src/render.ts @@ -1,10 +1,11 @@ import { - effectScope, + isArray, normalizeClass, normalizeStyle, toDisplayString -} from 'vue' -import { isArray } from '@vue/shared' +} from '@vue/shared' + +import { ComponentInternalInstance, createComponentInstance } from './component' export type Block = Node | Fragment | Block[] export type Fragment = { nodes: Block; anchor: Node } @@ -13,14 +14,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 { @@ -29,6 +26,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() + remove(block, container) + instance.isMounted = false + // TODO: lifecycle hooks (unmounted, ...) + // const { um } = instance + // um && invoke(um) +} + export const enum InsertPosition { FIRST, LAST From 895f91d2a83c7fdc21e74f6d17f467b62a4b2a78 Mon Sep 17 00:00:00 2001 From: Ubugeeei Date: Tue, 28 Nov 2023 23:25:26 +0900 Subject: [PATCH 2/2] chore: into nullable ComponentInternalInstance.block --- packages/runtime-vapor/src/component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index 6381f4ba1..02fc0d3ba 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -5,7 +5,7 @@ import { Block, BlockFn } from './render' export interface ComponentInternalInstance { uid: number container: ParentNode - block: Block + block: Block | null scope: EffectScope component: BlockFn @@ -20,7 +20,7 @@ export const createComponentInstance = ( ): ComponentInternalInstance => { const instance: ComponentInternalInstance = { uid: uid++, - block: null!, // set on mount + block: null, container: null!, // set on mount scope: new EffectScope(true /* detached */)!,