@@ -101,7 +101,7 @@ export function deactivate (view, transition, next) {
101101 * @param {Function } [cb]
102102 */
103103
104- export function activate ( view , transition , depth , cb ) {
104+ export function activate ( view , transition , depth , cb , reuse ) {
105105 let handler = transition . activateQueue [ depth ]
106106 if ( ! handler ) {
107107 // fix 1.0.0-alpha.3 compat
@@ -120,17 +120,61 @@ export function activate (view, transition, depth, cb) {
120120 view . depth = depth
121121 view . activated = false
122122
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+ }
132154 }
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+ }
134178
135179 // cleanup the component in case the transition is aborted
136180 // before the component is ever inserted.
@@ -162,7 +206,7 @@ export function activate (view, transition, depth, cb) {
162206 view . activated = true
163207 // activate the child view
164208 if ( view . childView ) {
165- activate ( view . childView , transition , depth + 1 )
209+ activate ( view . childView , transition , depth + 1 , null , reuse || view . keepAlive )
166210 }
167211 if ( dataHook && waitForData ) {
168212 // wait until data loaded to insert
@@ -172,7 +216,11 @@ export function activate (view, transition, depth, cb) {
172216 if ( dataHook ) {
173217 loadData ( component , transition , dataHook )
174218 }
175- insert ( )
219+ if ( ! reuse ) {
220+ insert ( )
221+ } else {
222+ cb && cb ( )
223+ }
176224 }
177225 }
178226
0 commit comments