From 6364b10be50db9e4df066ddd1d6d68ea68671c4c Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Wed, 27 Mar 2024 00:09:42 +0800 Subject: [PATCH 1/3] feat(runtime-vapor): createSlot --- .../__tests__/componentSlots.spec.ts | 8 +- packages/runtime-vapor/src/componentSlots.ts | 150 ++++++++++++------ packages/runtime-vapor/src/index.ts | 1 + 3 files changed, 112 insertions(+), 47 deletions(-) diff --git a/packages/runtime-vapor/__tests__/componentSlots.spec.ts b/packages/runtime-vapor/__tests__/componentSlots.spec.ts index c0e1b716f..6bd38826c 100644 --- a/packages/runtime-vapor/__tests__/componentSlots.spec.ts +++ b/packages/runtime-vapor/__tests__/componentSlots.spec.ts @@ -2,9 +2,11 @@ import { createComponent, + createSlot, createVaporApp, defineComponent, getCurrentInstance, + insert, nextTick, ref, template, @@ -41,11 +43,13 @@ describe('component: slots', () => { const t0 = template('
') const n0 = t0() instance = getCurrentInstance() + const n1 = createSlot('header') + insert(n1, n0 as any as ParentNode) return n0 }, }) - const { render } = define({ + const { render, host } = define({ render() { return createComponent(Comp, {}, { header: () => template('header')() }) }, @@ -56,6 +60,8 @@ describe('component: slots', () => { expect(instance.slots.header()).toMatchObject( document.createTextNode('header'), ) + + expect(host.innerHTML).toBe('
header
') }) // NOTE: slot normalization is not supported diff --git a/packages/runtime-vapor/src/componentSlots.ts b/packages/runtime-vapor/src/componentSlots.ts index 48ea4509c..705ecb077 100644 --- a/packages/runtime-vapor/src/componentSlots.ts +++ b/packages/runtime-vapor/src/componentSlots.ts @@ -1,8 +1,18 @@ -import { type IfAny, isArray } from '@vue/shared' -import { baseWatch } from '@vue/reactivity' -import { type ComponentInternalInstance, setCurrentInstance } from './component' -import type { Block } from './apiRender' -import { createVaporPreScheduler } from './scheduler' +import { type IfAny, isArray, isFunction } from '@vue/shared' +import { + type EffectScope, + effectScope, + isReactive, + shallowReactive, +} from '@vue/reactivity' +import { + type ComponentInternalInstance, + currentInstance, + setCurrentInstance, +} from './component' +import { type Block, type Fragment, fragmentKey } from './apiRender' +import { renderEffect } from './renderEffect' +import { createComment, createTextNode, insert, remove } from './dom/element' // TODO: SSR @@ -29,7 +39,7 @@ export const initSlots = ( rawSlots: InternalSlots | null = null, dynamicSlots: DynamicSlots | null = null, ) => { - const slots: InternalSlots = {} + let slots: InternalSlots = {} for (const key in rawSlots) { const slot = rawSlots[key] @@ -39,50 +49,45 @@ export const initSlots = ( } if (dynamicSlots) { + slots = shallowReactive(slots) const dynamicSlotKeys: Record = {} - baseWatch( - () => { - const _dynamicSlots = dynamicSlots() - for (let i = 0; i < _dynamicSlots.length; i++) { - const slot = _dynamicSlots[i] - // array of dynamic slot generated by