1
- import { ReactiveEffect , getCurrentScope } from '@vue/reactivity'
1
+ import {
2
+ type EffectScope ,
3
+ ReactiveEffect ,
4
+ getCurrentScope ,
5
+ } from '@vue/reactivity'
2
6
import {
3
7
type SchedulerJob ,
4
8
currentInstance ,
@@ -11,60 +15,87 @@ import {
11
15
import { type VaporComponentInstance , isVaporComponent } from './component'
12
16
import { invokeArrayFns } from '@vue/shared'
13
17
14
- export function renderEffect ( fn : ( ) => void , noLifecycle = false ) : void {
15
- const instance = currentInstance as VaporComponentInstance | null
16
- const scope = getCurrentScope ( )
17
- if ( __DEV__ && ! __TEST__ && ! scope && ! isVaporComponent ( instance ) ) {
18
- warn ( 'renderEffect called without active EffectScope or Vapor instance.' )
19
- }
18
+ class RenderEffect extends ReactiveEffect {
19
+ i : VaporComponentInstance | null
20
+ scope : EffectScope | undefined
21
+ baseJob : SchedulerJob
22
+ postJob : SchedulerJob
23
+
24
+ constructor (
25
+ private renderFn : ( ) => void ,
26
+ private noLifecycle = false ,
27
+ ) {
28
+ super ( )
29
+ const instance = currentInstance as VaporComponentInstance | null
30
+ const scope = getCurrentScope ( )
31
+ if ( __DEV__ && ! __TEST__ && ! scope && ! isVaporComponent ( instance ) ) {
32
+ warn ( 'renderEffect called without active EffectScope or Vapor instance.' )
33
+ }
34
+
35
+ this . baseJob = ( ) => {
36
+ if ( this . dirty ) {
37
+ this . run ( )
38
+ }
39
+ }
40
+ this . postJob = ( ) => {
41
+ instance ! . isUpdating = false
42
+ instance ! . u && invokeArrayFns ( instance ! . u )
43
+ }
20
44
21
- // renderEffect is always called after user has registered all hooks
22
- const hasUpdateHooks = instance && ( instance . bu || instance . u )
23
- const renderEffectFn = noLifecycle
24
- ? fn
25
- : ( ) => {
26
- if ( __DEV__ && instance ) {
27
- startMeasure ( instance , `renderEffect` )
28
- }
29
- const prev = currentInstance
30
- simpleSetCurrentInstance ( instance )
31
- if ( scope ) scope . on ( )
32
- if ( hasUpdateHooks && instance . isMounted && ! instance . isUpdating ) {
33
- instance . isUpdating = true
34
- instance . bu && invokeArrayFns ( instance . bu )
35
- fn ( )
36
- queuePostFlushCb ( ( ) => {
37
- instance . isUpdating = false
38
- instance . u && invokeArrayFns ( instance . u )
39
- } )
40
- } else {
41
- fn ( )
42
- }
43
- if ( scope ) scope . off ( )
44
- simpleSetCurrentInstance ( prev , instance )
45
- if ( __DEV__ && instance ) {
46
- startMeasure ( instance , `renderEffect` )
47
- }
45
+ if ( instance ) {
46
+ if ( __DEV__ ) {
47
+ this . onTrack = instance . rtc
48
+ ? e => invokeArrayFns ( instance . rtc ! , e )
49
+ : void 0
50
+ this . onTrigger = instance . rtg
51
+ ? e => invokeArrayFns ( instance . rtg ! , e )
52
+ : void 0
48
53
}
54
+ this . baseJob . i = instance
55
+ this . baseJob . id = instance . uid
56
+ }
57
+
58
+ this . i = instance
59
+ this . scope = scope
49
60
50
- const effect = new ReactiveEffect ( renderEffectFn )
51
- const job : SchedulerJob = ( ) => effect . dirty && effect . run ( )
61
+ // TODO recurse handling
62
+ }
52
63
53
- if ( instance ) {
54
- if ( __DEV__ ) {
55
- effect . onTrack = instance . rtc
56
- ? e => invokeArrayFns ( instance . rtc ! , e )
57
- : void 0
58
- effect . onTrigger = instance . rtg
59
- ? e => invokeArrayFns ( instance . rtg ! , e )
60
- : void 0
64
+ callback ( ) {
65
+ if ( this . noLifecycle ) {
66
+ this . renderFn ( )
67
+ return
68
+ }
69
+ const instance = this . i !
70
+ const scope = this . scope
71
+ // renderEffect is always called after user has registered all hooks
72
+ const hasUpdateHooks = instance && ( instance . bu || instance . u )
73
+ if ( __DEV__ && instance ) {
74
+ startMeasure ( instance , `renderEffect` )
75
+ }
76
+ const prev = currentInstance
77
+ simpleSetCurrentInstance ( instance )
78
+ if ( scope ) scope . on ( )
79
+ if ( hasUpdateHooks && instance . isMounted && ! instance . isUpdating ) {
80
+ instance . isUpdating = true
81
+ instance . bu && invokeArrayFns ( instance . bu )
82
+ this . renderFn ( )
83
+ queuePostFlushCb ( this . postJob )
84
+ } else {
85
+ this . renderFn ( )
86
+ }
87
+ if ( scope ) scope . off ( )
88
+ simpleSetCurrentInstance ( prev , instance )
89
+ if ( __DEV__ && instance ) {
90
+ startMeasure ( instance , `renderEffect` )
61
91
}
62
- job . i = instance
63
- job . id = instance . uid
64
92
}
65
93
66
- effect . scheduler = ( ) => queueJob ( job )
67
- effect . run ( )
94
+ scheduler ( ) {
95
+ queueJob ( this . baseJob )
96
+ }
97
+ }
68
98
69
- // TODO recurse handling
99
+ export function renderEffect ( fn : ( ) => void , noLifecycle = false ) : void {
100
+ new RenderEffect ( fn , noLifecycle ) . run ( )
70
101
}
0 commit comments