diff --git a/packages/runtime-core/__tests__/componentSlots.spec.ts b/packages/runtime-core/__tests__/componentSlots.spec.ts index 2cf50b964bf..ad87e5367d7 100644 --- a/packages/runtime-core/__tests__/componentSlots.spec.ts +++ b/packages/runtime-core/__tests__/componentSlots.spec.ts @@ -6,6 +6,7 @@ import { nodeOps, ref, render, + useSlots, } from '@vue/runtime-test' import { createBlock, normalizeVNode } from '../src/vnode' import { createSlots } from '../src/helpers/createSlots' @@ -42,6 +43,29 @@ describe('component: slots', () => { expect(slots).toMatchObject({}) }) + test('initSlots: ensure compiler marker non-enumerable', () => { + const Comp = { + render() { + const slots = useSlots() + // Only user-defined slots should be enumerable + expect(Object.keys(slots)).toEqual(['foo']) + + // Internal compiler markers must still exist but be non-enumerable + expect(slots).toHaveProperty('_') + expect(Object.getOwnPropertyDescriptor(slots, '_')!.enumerable).toBe( + false, + ) + expect(slots).toHaveProperty('__') + expect(Object.getOwnPropertyDescriptor(slots, '__')!.enumerable).toBe( + false, + ) + return h('div') + }, + } + const slots = { foo: () => {}, _: 1, __: [1] } + render(createBlock(Comp, null, slots), nodeOps.createElement('div')) + }) + test('initSlots: should normalize object slots (when value is null, string, array)', () => { const { slots } = renderWithSlots({ _inner: '_inner', diff --git a/packages/runtime-core/src/componentSlots.ts b/packages/runtime-core/src/componentSlots.ts index 3812695431e..6114f6c86cf 100644 --- a/packages/runtime-core/src/componentSlots.ts +++ b/packages/runtime-core/src/componentSlots.ts @@ -193,6 +193,10 @@ export const initSlots = ( ): void => { const slots = (instance.slots = createInternalObject()) if (instance.vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) { + const cacheIndexes = (children as RawSlots).__ + // make cache indexes marker non-enumerable + if (cacheIndexes) def(slots, '__', cacheIndexes, true) + const type = (children as RawSlots)._ if (type) { assignSlots(slots, children as Slots, optimized)