1
1
import {
2
2
type Component ,
3
3
createComponentInstance ,
4
- currentInstance ,
4
+ setCurrentInstance ,
5
5
} from './component'
6
6
import { setupComponent } from './apiRender'
7
7
import type { RawProps } from './componentProps'
8
8
import type { RawSlots } from './componentSlots'
9
9
import { withAttrs } from './componentAttrs'
10
+ import { getCurrentScope } from '@vue/reactivity'
11
+ import type { BlockEffectScope } from './blockEffectScope'
12
+ import {
13
+ type Directive ,
14
+ type DirectiveHookName ,
15
+ invokeDirectiveHook ,
16
+ } from './directives'
17
+ import { VaporLifecycleHooks } from './enums'
18
+ import { NOOP , invokeArrayFns } from '@vue/shared'
10
19
11
20
export function createComponent (
12
21
comp : Component ,
@@ -15,7 +24,7 @@ export function createComponent(
15
24
singleRoot : boolean = false ,
16
25
once : boolean = false ,
17
26
) {
18
- const current = currentInstance !
27
+ const parentScope = getCurrentScope ( ) as BlockEffectScope
19
28
const instance = createComponentInstance (
20
29
comp ,
21
30
singleRoot ? withAttrs ( rawProps ) : rawProps ,
@@ -24,8 +33,58 @@ export function createComponent(
24
33
)
25
34
setupComponent ( instance , singleRoot )
26
35
27
- // register sub-component with current component for lifecycle management
28
- current . comps . add ( instance )
36
+ const directiveBindingsMap = ( parentScope . dirs ||= new Map ( ) )
37
+ const dir : Directive = {
38
+ beforeMount : passDirectives (
39
+ VaporLifecycleHooks . BEFORE_MOUNT ,
40
+ 'beforeMount' ,
41
+ ) ,
42
+ mounted : passDirectives (
43
+ VaporLifecycleHooks . MOUNTED ,
44
+ 'mounted' ,
45
+ ( ) => ( instance . isMounted = true ) ,
46
+ true ,
47
+ ) ,
48
+ beforeUnmount : passDirectives (
49
+ VaporLifecycleHooks . BEFORE_UNMOUNT ,
50
+ 'beforeUnmount' ,
51
+ ) ,
52
+ unmounted : passDirectives (
53
+ VaporLifecycleHooks . UNMOUNTED ,
54
+ 'unmounted' ,
55
+ ( ) => ( instance . isUnmounted = true ) ,
56
+ true ,
57
+ ) ,
58
+ }
59
+ directiveBindingsMap . set ( instance , [
60
+ { dir, instance, value : null , oldValue : undefined } ,
61
+ ] )
29
62
30
63
return instance
64
+
65
+ function passDirectives (
66
+ lifecycle : VaporLifecycleHooks ,
67
+ directive : DirectiveHookName ,
68
+ cb = NOOP ,
69
+ reverse ?: boolean ,
70
+ ) {
71
+ const hooks = reverse
72
+ ? [ cb , callDirHooks , callLifecycleHooks ]
73
+ : [ callLifecycleHooks , callDirHooks , cb ]
74
+
75
+ return ( ) => invokeArrayFns ( hooks )
76
+
77
+ function callDirHooks ( ) {
78
+ invokeDirectiveHook ( instance , directive , instance . scope )
79
+ }
80
+ function callLifecycleHooks ( ) {
81
+ // lifecycle hooks may be mounted halfway.
82
+ const lifecycleHooks = instance [ lifecycle ]
83
+ if ( lifecycleHooks && lifecycleHooks . length ) {
84
+ const reset = setCurrentInstance ( instance )
85
+ instance . scope . run ( ( ) => invokeArrayFns ( lifecycleHooks ) )
86
+ reset ( )
87
+ }
88
+ }
89
+ }
31
90
}
0 commit comments