@@ -25,6 +25,12 @@ import { DynamicFragment, type VaporFragment } from './fragment'
2525import { createElement } from './dom/node'
2626import { setDynamicProps } from './dom/prop'
2727
28+ /**
29+ * Flag to indicate if we are executing a once slot.
30+ * When true, renderEffect should skip creating reactive effect.
31+ */
32+ export let inOnceSlot = false
33+
2834/**
2935 * Current slot scopeIds for vdom interop
3036 */
@@ -163,6 +169,7 @@ export function createSlot(
163169 rawProps ?: LooseRawProps | null ,
164170 fallback ?: VaporSlot ,
165171 noSlotted ?: boolean ,
172+ once ?: boolean ,
166173) : Block {
167174 const _insertionParent = insertionParent
168175 const _insertionAnchor = insertionAnchor
@@ -236,9 +243,12 @@ export function createSlot(
236243 const prevSlotScopeIds = setCurrentSlotScopeIds (
237244 slotScopeIds . length > 0 ? slotScopeIds : null ,
238245 )
246+ const prev = inOnceSlot
239247 try {
248+ if ( once ) inOnceSlot = true
240249 return slot ( slotProps )
241250 } finally {
251+ inOnceSlot = prev
242252 setCurrentSlotScopeIds ( prevSlotScopeIds )
243253 }
244254 } ) ,
@@ -249,7 +259,7 @@ export function createSlot(
249259 }
250260
251261 // dynamic slot name or has dynamicSlots
252- if ( isDynamicName || rawSlots . $ ) {
262+ if ( ! once && ( isDynamicName || rawSlots . $ ) ) {
253263 renderEffect ( renderSlot )
254264 } else {
255265 renderSlot ( )
0 commit comments