8
8
import { isArray , isFunction , EMPTY_OBJ , ShapeFlags } from '@vue/shared'
9
9
import { warn } from './warning'
10
10
import { isKeepAlive } from './components/KeepAlive'
11
+ import { withCtx } from './helpers/withRenderContext'
11
12
12
13
export type Slot = ( ...args : any [ ] ) => VNode [ ]
13
14
@@ -21,6 +22,9 @@ export type RawSlots = {
21
22
[ name : string ] : unknown
22
23
// manual render fn hint to skip forced children updates
23
24
$stable ?: boolean
25
+ // internal, for tracking slot owner instance. This is attached during
26
+ // normalizeChildren when the component vnode is created.
27
+ _ctx ?: ComponentInternalInstance | null
24
28
// internal, indicates compiler generated slots = can skip normalization
25
29
_ ?: 1
26
30
}
@@ -30,18 +34,21 @@ const normalizeSlotValue = (value: unknown): VNode[] =>
30
34
? value . map ( normalizeVNode )
31
35
: [ normalizeVNode ( value as VNodeChild ) ]
32
36
33
- const normalizeSlot = ( key : string , rawSlot : Function ) : Slot => (
34
- props : any
35
- ) => {
36
- if ( __DEV__ && currentInstance != null ) {
37
- warn (
38
- `Slot "${ key } " invoked outside of the render function: ` +
39
- `this will not track dependencies used in the slot. ` +
40
- `Invoke the slot function inside the render function instead.`
41
- )
42
- }
43
- return normalizeSlotValue ( rawSlot ( props ) )
44
- }
37
+ const normalizeSlot = (
38
+ key : string ,
39
+ rawSlot : Function ,
40
+ ctx : ComponentInternalInstance | null | undefined
41
+ ) : Slot =>
42
+ withCtx ( ( props : any ) => {
43
+ if ( __DEV__ && currentInstance != null ) {
44
+ warn (
45
+ `Slot "${ key } " invoked outside of the render function: ` +
46
+ `this will not track dependencies used in the slot. ` +
47
+ `Invoke the slot function inside the render function instead.`
48
+ )
49
+ }
50
+ return normalizeSlotValue ( rawSlot ( props ) )
51
+ } , ctx )
45
52
46
53
export function resolveSlots (
47
54
instance : ComponentInternalInstance ,
@@ -55,11 +62,12 @@ export function resolveSlots(
55
62
slots = children as Slots
56
63
} else {
57
64
slots = { }
65
+ const ctx = rawSlots . _ctx
58
66
for ( const key in rawSlots ) {
59
- if ( key === '$stable' ) continue
67
+ if ( key === '$stable' || key === '_ctx' ) continue
60
68
const value = rawSlots [ key ]
61
69
if ( isFunction ( value ) ) {
62
- slots [ key ] = normalizeSlot ( key , value )
70
+ slots [ key ] = normalizeSlot ( key , value , ctx )
63
71
} else if ( value != null ) {
64
72
if ( __DEV__ ) {
65
73
warn (
0 commit comments