inVOnce: boolean = false
inVFor: number = 0
- inSlot: number = 0
+ inSlot: boolean = false
comment: CommentNode[] = []
component: Set<string> = this.ir.component
ErrorCodes,
NodeTypes,
type SimpleExpressionNode,
- type TemplateChildNode,
createCompilerError,
createSimpleExpression,
isStaticArgOf,
}
return () => {
- const {
- block: { node: slotNode },
- inSlot,
- } = context
- const forwarded =
- inSlot !== 0 &&
- slotNode.type === NodeTypes.ELEMENT &&
- hasForwardedSlots(slotNode.children)
- if (forwarded) context.ir.hasForwardedSlot = true
-
+ if (context.inSlot) context.ir.hasForwardedSlot = true
exitBlock && exitBlock()
context.dynamic.operation = {
type: IRNodeTypes.SLOT_OUTLET_NODE,
name: slotName,
props: irProps,
fallback,
- forwarded,
+ forwarded: context.inSlot,
}
}
}
context.reference()
return [fallback, exitBlock]
}
-
-function hasForwardedSlots(children: TemplateChildNode[]): boolean {
- for (let i = 0; i < children.length; i++) {
- const child = children[i]
- switch (child.type) {
- case NodeTypes.ELEMENT:
- if (
- child.tagType === ElementTypes.SLOT ||
- hasForwardedSlots(child.children)
- ) {
- return true
- }
- break
- }
- }
- return false
-}
const block: SlotBlockIRNode = newBlock(slotNode)
block.props = dir && dir.exp
const exitBlock = context.enterBlock(block)
- context.inSlot++
+ context.inSlot = true
return [
block,
() => {
- context.inSlot--
+ context.inSlot = false
exitBlock()
},
]
await nextTick()
expect(host.innerHTML).toBe('bar<!--slot--><!--slot-->')
})
+
+ test('mixed with non-forwarded slot', async () => {
+ const Child = defineVaporComponent({
+ setup() {
+ return [createSlot('foo', null)]
+ },
+ })
+ const Parent = defineVaporComponent({
+ setup() {
+ const createForwardedSlot = forwardedSlotCreator()
+ const n2 = createComponent(Child, null, {
+ foo: () => {
+ const n0 = createForwardedSlot('foo', null)
+ return n0
+ },
+ })
+ const n3 = createSlot('default', null)
+ return [n2, n3]
+ },
+ })
+
+ const foo = ref('foo')
+ const { host } = define({
+ setup() {
+ const n2 = createComponent(
+ Parent,
+ null,
+ {
+ foo: () => {
+ const n0 = template(' ')() as any
+ renderEffect(() => setText(n0, foo.value))
+ return n0
+ },
+ default: () => {
+ const n3 = template(' ')() as any
+ renderEffect(() => setText(n3, foo.value))
+ return n3
+ },
+ },
+ true,
+ )
+ return n2
+ },
+ }).render()
+
+ expect(host.innerHTML).toBe('foo<!--slot--><!--slot-->foo<!--slot-->')
+
+ foo.value = 'bar'
+ await nextTick()
+ expect(host.innerHTML).toBe('bar<!--slot--><!--slot-->bar<!--slot-->')
+ })
})
})
fallback?: VaporSlot,
) => Block {
const instance = currentInstance as VaporComponentInstance
- return (
- name: string | (() => string),
- rawProps?: LooseRawProps | null,
- fallback?: VaporSlot,
- ) => createSlot(name, rawProps, fallback, instance)
+ return (name, rawProps, fallback) =>
+ createSlot(name, rawProps, fallback, instance)
}
export function createSlot(