diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
index 9b66bb6c869..e3251a687d9 100644
--- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
+++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
@@ -228,6 +228,25 @@ export function render(_ctx) {
}"
`;
+exports[`compiler: transform slot > nested component should not inherit parent slots 1`] = `
+"import { resolveComponent as _resolveComponent, withVaporCtx as _withVaporCtx, createComponentWithFallback as _createComponentWithFallback } from 'vue';
+
+export function render(_ctx) {
+ const _component_Bar = _resolveComponent("Bar")
+ const _component_Foo = _resolveComponent("Foo")
+ const n2 = _createComponentWithFallback(_component_Foo, null, {
+ "header": _withVaporCtx(() => {
+ return null
+ }),
+ "default": _withVaporCtx(() => {
+ const n1 = _createComponentWithFallback(_component_Bar)
+ return n1
+ })
+ }, true)
+ return n2
+}"
+`;
+
exports[`compiler: transform slot > nested component slot 1`] = `
"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, withVaporCtx as _withVaporCtx } from 'vue';
diff --git a/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts b/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
index 64d1b4ac4a4..093f1d577be 100644
--- a/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
+++ b/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
@@ -155,6 +155,16 @@ describe('compiler: transform slot', () => {
})
})
+ test('nested component should not inherit parent slots', () => {
+ const { code } = compileWithSlots(`
+
+
+
+
+ `)
+ expect(code).toMatchSnapshot()
+ })
+
test('named slots w/ implicit default slot', () => {
const { ir, code } = compileWithSlots(
`
diff --git a/packages/compiler-vapor/src/transforms/transformElement.ts b/packages/compiler-vapor/src/transforms/transformElement.ts
index dc9c7e0aae0..312800a093a 100644
--- a/packages/compiler-vapor/src/transforms/transformElement.ts
+++ b/packages/compiler-vapor/src/transforms/transformElement.ts
@@ -37,6 +37,7 @@ import {
type IRProps,
type IRPropsDynamicAttribute,
type IRPropsStatic,
+ type IRSlots,
type VaporDirectiveNode,
} from '../ir'
import { EMPTY_EXPRESSION } from './utils'
@@ -51,6 +52,20 @@ export const isReservedProp: (key: string) => boolean = /*#__PURE__*/ makeMap(
export const transformElement: NodeTransform = (node, context) => {
let effectIndex = context.block.effect.length
const getEffectIndex = () => effectIndex++
+
+ // If the element is a component, we need to isolate its slots context.
+ // This ensures that slots defined for this component are not accidentally
+ // inherited by its children components.
+ let parentSlots: IRSlots[] | undefined
+ if (
+ node.type === NodeTypes.ELEMENT &&
+ (node.tagType === ElementTypes.COMPONENT ||
+ context.options.isCustomElement(node.tag))
+ ) {
+ parentSlots = context.slots
+ context.slots = []
+ }
+
return function postTransformElement() {
;({ node } = context)
if (
@@ -96,6 +111,10 @@ export const transformElement: NodeTransform = (node, context) => {
getEffectIndex,
)
}
+
+ if (parentSlots) {
+ context.slots = parentSlots
+ }
}
}