@@ -23,7 +23,8 @@ import {
23
23
queuePostRenderEffect ,
24
24
MoveType ,
25
25
RendererElement ,
26
- RendererNode
26
+ RendererNode ,
27
+ invokeVNodeHook
27
28
} from '../renderer'
28
29
import { setTransitionHooks } from './BaseTransition'
29
30
import { ComponentRenderContext } from '../componentProxy'
@@ -96,11 +97,11 @@ const KeepAliveImpl = {
96
97
const storageContainer = createElement ( 'div' )
97
98
98
99
sharedContext . activate = ( vnode , container , anchor , isSVG , optimized ) => {
99
- const child = vnode . component !
100
+ const instance = vnode . component !
100
101
move ( vnode , container , anchor , MoveType . ENTER , parentSuspense )
101
102
// in case props have changed
102
103
patch (
103
- child . vnode ,
104
+ instance . vnode ,
104
105
vnode ,
105
106
container ,
106
107
anchor ,
@@ -110,27 +111,35 @@ const KeepAliveImpl = {
110
111
optimized
111
112
)
112
113
queuePostRenderEffect ( ( ) => {
113
- child . isDeactivated = false
114
- if ( child . a ) {
115
- invokeArrayFns ( child . a )
114
+ instance . isDeactivated = false
115
+ if ( instance . a ) {
116
+ invokeArrayFns ( instance . a )
117
+ }
118
+ const vnodeHook = vnode . props && vnode . props . onVnodeMounted
119
+ if ( vnodeHook ) {
120
+ invokeVNodeHook ( vnodeHook , instance . parent , vnode )
116
121
}
117
122
} , parentSuspense )
118
123
}
119
124
120
125
sharedContext . deactivate = ( vnode : VNode ) => {
126
+ const instance = vnode . component !
121
127
move ( vnode , storageContainer , null , MoveType . LEAVE , parentSuspense )
122
128
queuePostRenderEffect ( ( ) => {
123
- const component = vnode . component !
124
- if ( component . da ) {
125
- invokeArrayFns ( component . da )
129
+ if ( instance . da ) {
130
+ invokeArrayFns ( instance . da )
131
+ }
132
+ const vnodeHook = vnode . props && vnode . props . onVnodeUnmounted
133
+ if ( vnodeHook ) {
134
+ invokeVNodeHook ( vnodeHook , instance . parent , vnode )
126
135
}
127
- component . isDeactivated = true
136
+ instance . isDeactivated = true
128
137
} , parentSuspense )
129
138
}
130
139
131
140
function unmount ( vnode : VNode ) {
132
141
// reset the shapeFlag so it can be properly unmounted
133
- vnode . shapeFlag = ShapeFlags . STATEFUL_COMPONENT
142
+ resetShapeFlag ( vnode )
134
143
_unmount ( vnode , instance , parentSuspense )
135
144
}
136
145
@@ -150,7 +159,7 @@ const KeepAliveImpl = {
150
159
} else if ( current ) {
151
160
// current active instance should no longer be kept-alive.
152
161
// we can't unmount it now but it might be later, so reset its flag now.
153
- current . shapeFlag = ShapeFlags . STATEFUL_COMPONENT
162
+ resetShapeFlag ( current )
154
163
}
155
164
cache . delete ( key )
156
165
keys . delete ( key )
@@ -165,7 +174,18 @@ const KeepAliveImpl = {
165
174
)
166
175
167
176
onBeforeUnmount ( ( ) => {
168
- cache . forEach ( unmount )
177
+ cache . forEach ( cached => {
178
+ const { subTree, suspense } = instance
179
+ if ( cached . type === subTree . type ) {
180
+ // current instance will be unmounted as part of keep-alive's unmount
181
+ resetShapeFlag ( subTree )
182
+ // but invoke its deactivated hook here
183
+ const da = subTree . component ! . da
184
+ da && queuePostRenderEffect ( da , suspense )
185
+ return
186
+ }
187
+ unmount ( cached )
188
+ } )
169
189
} )
170
190
171
191
return ( ) => {
@@ -197,7 +217,7 @@ const KeepAliveImpl = {
197
217
( include && ( ! name || ! matches ( include , name ) ) ) ||
198
218
( exclude && name && matches ( exclude , name ) )
199
219
) {
200
- return vnode
220
+ return ( current = vnode )
201
221
}
202
222
203
223
const key = vnode . key == null ? comp : vnode . key
@@ -325,3 +345,14 @@ function injectToKeepAliveRoot(
325
345
remove ( keepAliveRoot [ type ] ! , hook )
326
346
} , target )
327
347
}
348
+
349
+ function resetShapeFlag ( vnode : VNode ) {
350
+ let shapeFlag = vnode . shapeFlag
351
+ if ( shapeFlag & ShapeFlags . COMPONENT_SHOULD_KEEP_ALIVE ) {
352
+ shapeFlag -= ShapeFlags . COMPONENT_SHOULD_KEEP_ALIVE
353
+ }
354
+ if ( shapeFlag & ShapeFlags . COMPONENT_KEPT_ALIVE ) {
355
+ shapeFlag -= ShapeFlags . COMPONENT_KEPT_ALIVE
356
+ }
357
+ vnode . shapeFlag = shapeFlag
358
+ }
0 commit comments