vue3-core/packages/runtime-vapor/src/component.ts

98 lines
2.3 KiB
TypeScript
Raw Normal View History

import { EffectScope, Ref, ref } from '@vue/reactivity'
import { EMPTY_OBJ } from '@vue/shared'
import { Block } from './render'
import { type DirectiveBinding } from './directive'
import {
type ComponentPropsOptions,
type NormalizedPropsOptions,
normalizePropsOptions,
} from './componentProps'
2023-12-07 01:51:57 +08:00
import type { Data } from '@vue/shared'
export type Component = FunctionalComponent | ObjectComponent
2023-12-06 14:59:11 +08:00
export type SetupFn = (props: any, ctx: any) => Block | Data
export type FunctionalComponent = SetupFn & {
props: ComponentPropsOptions
2023-12-06 14:59:11 +08:00
render(ctx: any): Block
}
export interface ObjectComponent {
props: ComponentPropsOptions
setup?: SetupFn
2023-12-06 14:59:11 +08:00
render(ctx: any): Block
}
export interface ComponentInternalInstance {
uid: number
container: ParentNode
block: Block | null
scope: EffectScope
2023-12-06 14:59:11 +08:00
component: FunctionalComponent | ObjectComponent
propsOptions: NormalizedPropsOptions
// TODO: type
proxy: Data | null
// state
props: Data
setupState: Data
2023-12-03 18:36:01 +08:00
/** directives */
dirs: Map<Node, DirectiveBinding[]>
// lifecycle
get isMounted(): boolean
isMountedRef: Ref<boolean>
// TODO: registory of provides, appContext, lifecycles, ...
}
2023-12-03 18:36:01 +08:00
// TODO
export let currentInstance: ComponentInternalInstance | null = null
export const getCurrentInstance: () => ComponentInternalInstance | null = () =>
currentInstance
export const setCurrentInstance = (instance: ComponentInternalInstance) => {
currentInstance = instance
}
export const unsetCurrentInstance = () => {
currentInstance = null
}
let uid = 0
export const createComponentInstance = (
2023-12-06 14:59:11 +08:00
component: ObjectComponent | FunctionalComponent,
): ComponentInternalInstance => {
2023-12-08 17:34:33 +08:00
const isMountedRef = ref(false)
const instance: ComponentInternalInstance = {
uid: uid++,
block: null,
container: null!, // set on mount
scope: new EffectScope(true /* detached */)!,
component,
// resolved props and emits options
propsOptions: normalizePropsOptions(component),
// emitsOptions: normalizeEmitsOptions(type, appContext), // TODO:
proxy: null,
// state
props: EMPTY_OBJ,
setupState: EMPTY_OBJ,
dirs: new Map(),
// lifecycle
2023-12-08 17:34:33 +08:00
get isMounted() {
return isMountedRef.value
},
isMountedRef,
// TODO: registory of provides, appContext, lifecycles, ...
}
return instance
}