Skip to content

Commit f968c1c

Browse files
committed
chore: tweak slot parent instance
1 parent 66d3a31 commit f968c1c

File tree

4 files changed

+41
-28
lines changed

4 files changed

+41
-28
lines changed

packages/runtime-core/src/apiCreateApp.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,12 @@ export interface VaporInteropInterface {
212212
transition: TransitionHooks,
213213
): void
214214

215-
vdomMount: (component: ConcreteComponent, props?: any, slots?: any) => any
215+
vdomMount: (
216+
component: ConcreteComponent,
217+
parentComponent: any,
218+
props?: any,
219+
slots?: any,
220+
) => any
216221
vdomUnmount: UnmountComponentFn
217222
vdomSlot: (
218223
slots: any,

packages/runtime-vapor/src/component.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,14 @@ export function createComponent(
225225

226226
// vdom interop enabled and component is not an explicit vapor component
227227
if (appContext.vapor && !component.__vapor) {
228+
const prevUseSlotConsumer = setUseSlotConsumer(false)
228229
const frag = appContext.vapor.vdomMount(
229230
component as any,
231+
parentInstance as any,
230232
rawProps,
231233
rawSlots,
232234
)
233-
235+
setUseSlotConsumer(prevUseSlotConsumer)
234236
if (!isHydrating) {
235237
if (_insertionParent) insert(frag, _insertionParent, _insertionAnchor)
236238
} else {
@@ -266,6 +268,9 @@ export function createComponent(
266268
parentInstance,
267269
)
268270

271+
// set useSlotConsumer to false to avoid affecting the child components
272+
const prevUseSlotConsumer = setUseSlotConsumer(false)
273+
269274
// HMR
270275
if (__DEV__ && component.__hmrId) {
271276
registerHMR(instance)
@@ -324,6 +329,8 @@ export function createComponent(
324329
setupComponent(instance, component)
325330
}
326331

332+
// reset useSlotConsumer to previous value after setupFn call is finished
333+
setUseSlotConsumer(prevUseSlotConsumer)
327334
onScopeDispose(() => unmountComponent(instance), true)
328335

329336
if (_insertionParent || isHydrating) {
@@ -333,6 +340,7 @@ export function createComponent(
333340
if (isHydrating && _insertionAnchor !== undefined) {
334341
advanceHydrationNode(_insertionParent!)
335342
}
343+
336344
return instance
337345
}
338346

@@ -611,8 +619,6 @@ export class VaporComponentInstance implements GenericComponentInstance {
611619
if (comp.ce) {
612620
comp.ce(this)
613621
}
614-
615-
setUseSlotConsumer(false)
616622
}
617623

618624
/**

packages/runtime-vapor/src/componentSlots.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,19 @@ function setCurrentSlotConsumer(consumer: GenericComponentInstance | null) {
142142
}
143143

144144
export let useSlotConsumer = false
145-
export function setUseSlotConsumer(value: boolean): void {
146-
useSlotConsumer = value
145+
export function setUseSlotConsumer(value: boolean): boolean {
146+
try {
147+
return useSlotConsumer
148+
} finally {
149+
useSlotConsumer = value
150+
}
147151
}
148152

153+
// when rendering components in slot, currentInstance is changed in withVaporCtx
154+
// should use currentSlotConsumer as parent until new instance is created
155+
// it requires to be set to false after new instance is created to avoid affecting
156+
// the child components and reset to previous value after setupFn call is finished
149157
export function getParentInstance(): GenericComponentInstance | null {
150-
// when rendering components in slot, currentInstance is changed in withVaporCtx
151-
// should use currentSlotConsumer as parent until new instance is created
152158
return useSlotConsumer ? currentSlotConsumer : currentInstance
153159
}
154160

@@ -160,17 +166,17 @@ export function getParentInstance(): GenericComponentInstance | null {
160166
export function withVaporCtx(fn: Function): BlockFn {
161167
const owner = currentInstance
162168
return (...args: any[]) => {
163-
useSlotConsumer = true
164169
const prev = setCurrentInstance(owner)
165170
const prevOwner = setCurrentSlotOwner(owner)
166171
const prevConsumer = setCurrentSlotConsumer(prev[0])
172+
const prevUseSlotConsumer = setUseSlotConsumer(true)
167173
try {
168174
return fn(...args)
169175
} finally {
170-
setCurrentSlotConsumer(prevConsumer)
171-
setCurrentSlotOwner(prevOwner)
172176
setCurrentInstance(...prev)
173-
useSlotConsumer = false
177+
setCurrentSlotOwner(prevOwner)
178+
setCurrentSlotConsumer(prevConsumer)
179+
setUseSlotConsumer(prevUseSlotConsumer)
174180
}
175181
}
176182
}

packages/runtime-vapor/src/vdomInterop.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,7 @@ import {
5959
} from '@vue/shared'
6060
import { type RawProps, rawPropsProxyHandlers } from './componentProps'
6161
import type { RawSlots, VaporSlot } from './componentSlots'
62-
import {
63-
currentSlotOwner,
64-
currentSlotScopeIds,
65-
getParentInstance,
66-
} from './componentSlots'
62+
import { currentSlotOwner, currentSlotScopeIds } from './componentSlots'
6763
import { renderEffect } from './renderEffect'
6864
import { _next, createTextNode } from './dom/node'
6965
import { optimizePropertyLookup } from './dom/prop'
@@ -277,10 +273,10 @@ let vdomHydrateNode: HydrationRenderer['hydrateNode'] | undefined
277273
function createVDOMComponent(
278274
internals: RendererInternals,
279275
component: ConcreteComponent,
276+
parentComponent: VaporComponentInstance | null,
280277
rawProps?: LooseRawProps | null,
281278
rawSlots?: LooseRawSlots | null,
282279
): VaporFragment {
283-
const parentInstance = getParentInstance() as VaporComponentInstance | null
284280
const frag = new VaporFragment([])
285281
const vnode = (frag.vnode = createVNode(
286282
component,
@@ -290,9 +286,9 @@ function createVDOMComponent(
290286
{ props: component.props },
291287
rawProps as RawProps,
292288
rawSlots as RawSlots,
293-
parentInstance ? parentInstance.appContext : undefined,
289+
parentComponent ? parentComponent.appContext : undefined,
294290
undefined,
295-
parentInstance,
291+
parentComponent,
296292
)
297293

298294
// overwrite how the vdom instance handles props
@@ -322,9 +318,9 @@ function createVDOMComponent(
322318
if (vnode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {
323319
vdomDeactivate(
324320
vnode,
325-
findParentKeepAlive(parentInstance!)!.getStorageContainer(),
321+
findParentKeepAlive(parentComponent!)!.getStorageContainer(),
326322
internals,
327-
parentInstance as any,
323+
parentComponent as any,
328324
null,
329325
)
330326
return
@@ -333,13 +329,13 @@ function createVDOMComponent(
333329
}
334330

335331
frag.hydrate = () => {
336-
hydrateVNode(vnode, parentInstance as any)
332+
hydrateVNode(vnode, parentComponent as any)
337333
onScopeDispose(unmount, true)
338334
isMounted = true
339335
frag.nodes = vnode.el as any
340336
}
341337

342-
const scopeOwner = currentSlotOwner || parentInstance
338+
const scopeOwner = currentSlotOwner || parentComponent
343339
vnode.scopeId = (scopeOwner && scopeOwner.type.__scopeId) || null
344340
vnode.slotScopeIds = currentSlotScopeIds
345341

@@ -351,21 +347,21 @@ function createVDOMComponent(
351347
parentNode,
352348
anchor,
353349
internals,
354-
parentInstance as any,
350+
parentComponent as any,
355351
null,
356352
undefined,
357353
false,
358354
)
359355
} else {
360356
const prev = currentInstance
361-
simpleSetCurrentInstance(parentInstance)
357+
simpleSetCurrentInstance(parentComponent)
362358
if (!isMounted) {
363359
if (transition) setVNodeTransitionHooks(vnode, transition)
364360
internals.mt(
365361
vnode,
366362
parentNode,
367363
anchor,
368-
parentInstance as any,
364+
parentComponent as any,
369365
null,
370366
undefined,
371367
false,
@@ -381,7 +377,7 @@ function createVDOMComponent(
381377
parentNode,
382378
anchor,
383379
MoveType.REORDER,
384-
parentInstance as any,
380+
parentComponent as any,
385381
)
386382
}
387383
simpleSetCurrentInstance(prev)

0 commit comments

Comments
 (0)