fix(slots): make cache indexes marker non-enumerable (#13469)

close #13468
This commit is contained in:
edison 2025-06-18 20:53:48 +08:00 committed by GitHub
parent cb14b860f1
commit 919c44744b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 0 deletions

View File

@ -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',

View File

@ -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)