@@ -101,7 +101,7 @@ export function deactivate (view, transition, next) {
101
101
* @param {Function } [cb]
102
102
*/
103
103
104
- export function activate ( view , transition , depth , cb ) {
104
+ export function activate ( view , transition , depth , cb , reuse ) {
105
105
let handler = transition . activateQueue [ depth ]
106
106
if ( ! handler ) {
107
107
// fix 1.0.0-alpha.3 compat
@@ -120,17 +120,61 @@ export function activate (view, transition, depth, cb) {
120
120
view . depth = depth
121
121
view . activated = false
122
122
123
- // unbuild current component. this step also destroys
124
- // and removes all nested child views.
125
- view . unbuild ( true )
126
- // build the new component. this will also create the
127
- // direct child view of the current one. it will register
128
- // itself as view.childView.
129
- let component = view . build ( {
130
- _meta : {
131
- $loadingRouteData : ! ! ( dataHook && ! waitForData )
123
+ let component
124
+ let loading = ! ! ( dataHook && ! waitForData )
125
+
126
+ // "reuse" is a flag passed down when the parent view is
127
+ // either reused via keep-alive or as a child of a kept-alive view.
128
+ // of course we can only reuse if the current kept-alive instance
129
+ // is of the correct type.
130
+ reuse = reuse && view . childVM && view . childVM . constructor === Component
131
+
132
+ if ( reuse ) {
133
+ // just reuse
134
+ component = view . childVM
135
+ component . $loadingRouteData = loading
136
+ } else {
137
+ // unbuild current component. this step also destroys
138
+ // and removes all nested child views.
139
+ view . unbuild ( true )
140
+ // handle keep-alive.
141
+ // if the view has keep-alive, the child vm is not actually
142
+ // destroyed - its nested views will still be in router's
143
+ // view list. We need to removed these child views and
144
+ // cache them on the child vm.
145
+ if ( view . keepAlive ) {
146
+ let views = transition . router . _views
147
+ let i = views . indexOf ( view )
148
+ if ( i > 0 ) {
149
+ transition . router . _views = views . slice ( i )
150
+ if ( view . childVM ) {
151
+ view . childVM . _routerViews = views . slice ( 0 , i )
152
+ }
153
+ }
132
154
}
133
- } )
155
+
156
+ // build the new component. this will also create the
157
+ // direct child view of the current one. it will register
158
+ // itself as view.childView.
159
+ component = view . build ( {
160
+ _meta : {
161
+ $loadingRouteData : loading
162
+ }
163
+ } )
164
+ // handle keep-alive.
165
+ // when a kept-alive child vm is restored, we need to
166
+ // add its cached child views into the router's view list,
167
+ // and also properly update current view's child view.
168
+ if ( view . keepAlive ) {
169
+ component . $loadingRouteData = loading
170
+ let cachedViews = component . _routerViews
171
+ if ( cachedViews ) {
172
+ transition . router . _views = cachedViews . concat ( transition . router . _views )
173
+ view . childView = cachedViews [ cachedViews . length - 1 ]
174
+ component . _routerViews = null
175
+ }
176
+ }
177
+ }
134
178
135
179
// cleanup the component in case the transition is aborted
136
180
// before the component is ever inserted.
@@ -162,7 +206,7 @@ export function activate (view, transition, depth, cb) {
162
206
view . activated = true
163
207
// activate the child view
164
208
if ( view . childView ) {
165
- activate ( view . childView , transition , depth + 1 )
209
+ activate ( view . childView , transition , depth + 1 , null , reuse || view . keepAlive )
166
210
}
167
211
if ( dataHook && waitForData ) {
168
212
// wait until data loaded to insert
@@ -172,7 +216,11 @@ export function activate (view, transition, depth, cb) {
172
216
if ( dataHook ) {
173
217
loadData ( component , transition , dataHook )
174
218
}
175
- insert ( )
219
+ if ( ! reuse ) {
220
+ insert ( )
221
+ } else {
222
+ cb && cb ( )
223
+ }
176
224
}
177
225
}
178
226
0 commit comments