fix(slots): refine internal key checking to support slot names starting with an underscore (#13612)

close #13611
This commit is contained in:
edison 2025-07-23 08:40:20 +08:00 committed by GitHub
parent a9269c642b
commit c5f7db1154
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 26 additions and 2 deletions

View File

@ -6,6 +6,7 @@ import {
nodeOps,
ref,
render,
serializeInner,
useSlots,
} from '@vue/runtime-test'
import { createBlock, normalizeVNode } from '../src/vnode'
@ -74,6 +75,10 @@ describe('component: slots', () => {
footer: ['f1', 'f2'],
})
expect(
'[Vue warn]: Non-function value encountered for slot "_inner". Prefer function slots for better performance.',
).toHaveBeenWarned()
expect(
'[Vue warn]: Non-function value encountered for slot "header". Prefer function slots for better performance.',
).toHaveBeenWarned()
@ -82,8 +87,8 @@ describe('component: slots', () => {
'[Vue warn]: Non-function value encountered for slot "footer". Prefer function slots for better performance.',
).toHaveBeenWarned()
expect(slots).not.toHaveProperty('_inner')
expect(slots).not.toHaveProperty('foo')
expect(slots._inner()).toMatchObject([normalizeVNode('_inner')])
expect(slots.header()).toMatchObject([normalizeVNode('header')])
expect(slots.footer()).toMatchObject([
normalizeVNode('f1'),
@ -442,4 +447,22 @@ describe('component: slots', () => {
'Slot "default" invoked outside of the render function',
).toHaveBeenWarned()
})
test('slot name starts with underscore', () => {
const Comp = {
setup(_: any, { slots }: any) {
return () => slots._foo()
},
}
const App = {
setup() {
return () => h(Comp, null, { _foo: () => 'foo' })
},
}
const root = nodeOps.createElement('div')
createApp(App).mount(root)
expect(serializeInner(root)).toBe('foo')
})
})

View File

@ -86,7 +86,8 @@ export type RawSlots = {
__?: number[]
}
const isInternalKey = (key: string) => key[0] === '_' || key === '$stable'
const isInternalKey = (key: string) =>
key === '_' || key === '__' || key === '_ctx' || key === '$stable'
const normalizeSlotValue = (value: unknown): VNode[] =>
isArray(value)