Latest
N/A
Change routes using router.go()
Specific routes to be kept alive, and some not.
My routing map might not be properly configured.
All routes are being kept alive but the canReuse() hook is not being called.
Here's my map:
Router.map( {
'/public': {
component: require( './routes/public/public-comp.vue' ), // template: <template><router-view></router-view></template>
subRoutes: {
'/login': {
component: require( './routes/public/login/login.vue' ),
name: 'public.login'
},
'/about': {
component: require( './routes/public/about/about.vue' ),
name: 'public.about'
},
'/register': {
component: require( './routes/public/register/register.vue' ),
name: 'public.register'
},
'/recovery': {
component: require( './routes/public/recovery/recovery.vue' ),
name: 'public.recovery'
}
}
},
'/user': {
component: require( './routes/user/user-comp.vue' ), // template: <template><router-view keep-alive></router-view></template>
subRoutes: {
'/map': {
component: require( './routes/map/map-comp.vue' ),
name: 'map.index',
map: true
},
'/contactsalive': {
component: require( './routes/contacts/contacts/contactsalive.vue' ),
name: 'contacts.index'
},
'/contacts': {
component: require( './routes/contacts/contacts-comp.vue' ), // template: <template><router-view></router-view></template>
subRoutes: {
'/edit/:uname': {
component: require( './routes/contacts/edit/contacts-edit.vue' ),
name: 'contacts.edit'
}
}
},
'/activities': {
component: require( './routes/activities/activities-comp.vue' ),
name: 'activities.index'
}
}
}
} )
I would only like the map and contactsalive route to be kept alive.
When I add this hook:
canReuse: function ( trans ) {
console.warn( 'canReuse >' )
return false
}
to the contacts-comp.vue component (the component I don't want kept alive), it never even gets called or 'canReuse >' never even gets logged.
I don't believe anything is wrong with anything on your end, I just thought I'd double check.
Thank you!!!
I'm trying something like:
Router.afterEach( function ( trans ) {
console.warn( 'Router.afterEach > trans >', trans )
if ( trans.from.KILL_ME == true ) {
console.log( 'BEFORE > afterEach > _children >', trans.to.router._children )
var i, len = trans.to.router._children.length
for ( i = 0; i < len; i++ ) {
if ( trans.to.router._children[ i ] ) {
if ( trans.to.router._children[ i ].KILL_ME ) {
console.log( 'trans.to.router._children[ ' + i + ' ].KILL_ME >', trans.to.router._children[ i ].KILL_ME )
console.warn( 'DESTROYING >', i )
trans.to.router._children[ i ].$destroy( true )
}
}
}
console.log( 'AFTER > afterEach > _children >', trans.to.router._children )
}
} )
but having no luck so far :(
I'm having luck with toggling:
trans.to.router._children[ i ]._routerView.keepAlive = false
trans.to.router._children[ i ]._routerView.params.keepAlive = false
And no luck with this:
Router.beforeEach( function ( trans ) {
console.log( 'trans >', trans )
if ( trans.to.KEEP_ME ) {
trans.to.router._rootView.keepAlive = true
trans.to.router._rootView.params.keepAlive = true
} else {
trans.to.router._rootView.keepAlive = false
trans.to.router._rootView.params.keepAlive = false
}
})
@yyx990803 Is this something that you'd be interested in supporting?
I'm looking at a similar use case right now, where we want to specify for one (top-level) route to be kept and all others to be re-initialised.
I wonder if it's a good idea to call canReuse for each component or allow an additional property on the route definition to distinguish the two or if we should roll our own thing to handle this?
If vue-router is interested in this, I'm happy to give it a go to write (and help maintaining) that change
+1 :D
Agreed, this would be great...
@yyx990803 This is a game changer for hybrid mobile app development with Cordova. No more lag between page transitions.
I had the same issue...
When using keep-alive, data is shared across multi component instances, though I returned a function in component.data.
I'd like to set canReuse=false, but the function is never called.
export default {
data() {
return {
...
}
},
methods: {
...
},
route: {
canReuse: function (transition) {
alert(1);
transition.next()
}
},
components: {
...
}
@virusdefender
What I ended up doing was setting up root routes to be keep-alive and put other non keep-alive routes in a static subroute.
Here's my router config:
Router.map( {
'/map': {
component: require( './routes/map/map-comp.vue' ),
name: 'map.index',
map: true
},
'/contacts-index': {
component: require( './routes/contacts/contacts/contacts-comp.vue' ),
name: 'contacts.index'
},
'/activities': {
component: require( './routes/activities/activities-comp.vue' ),
name: 'activities.index'
},
'/static': {
component: require( './routes/static/static-comp.vue' ),
subRoutes: {
'/public': {
component: require( './routes/public/public-comp.vue' ),
subRoutes: {
'/login': {
component: require( './routes/public/login/login.vue' ),
name: 'public.login'
},
'/about': {
component: require( './routes/public/about/about.vue' ),
name: 'public.about'
},
'/register': {
component: require( './routes/public/register/register.vue' ),
name: 'public.register'
},
'/recovery': {
component: require( './routes/public/recovery/recovery.vue' ),
name: 'public.recovery'
},
'/privacy': {
component: require( './routes/static/privacy/privacy.vue' ),
name: 'public.privacy'
},
'/terms': {
component: require( './routes/static/terms/terms.vue' ),
name: 'public.terms'
}
}
},
'/intro': {
component: require( './routes/intro/intro-comp.vue' ),
subRoutes: {
'/0': {
component: require( './routes/intro/0/0.vue' ),
name: 'intro.0'
},
'/1': {
component: require( './routes/intro/1/1.vue' ),
name: 'intro.1'
},
'/2': {
component: require( './routes/intro/2/2.vue' ),
name: 'intro.2'
},
'/3': {
component: require( './routes/intro/3/3.vue' ),
name: 'intro.3'
},
}
},
'/contacts': {
component: require( './routes/contacts/contacts.vue' ),
subRoutes: {
'/contacts-edit/:uname': {
component: require( './routes/contacts/edit/contacts-edit.vue' ),
name: 'contacts.edit'
},
'/comrades/:uname': {
component: require( './routes/contacts/comrades/comrades.vue' ),
name: 'contacts.comrades'
},
'/pending': {
component: require( './routes/contacts/pending/pending.vue' ),
name: 'contacts.pending'
},
'/adduname': {
component: require( './routes/contacts/adduname/adduname.vue' ),
name: 'contacts.adduname'
},
'/chat/:uname': {
component: require( './routes/contacts/chat/chat.vue' ),
name: 'contacts.chat'
},
'/phonelist': {
component: require( './routes/contacts/phonelist/phonelist.vue' ),
name: 'contacts.phonelist'
},
'/chooseadd': {
component: require( './routes/contacts/chooseadd/chooseadd.vue' ),
name: 'contacts.chooseadd'
},
}
},
'/settings': {
component: require( './routes/settings/settings-comp.vue' ),
subRoutes: {
'/index': {
component: require( './routes/settings/settings/settings.vue' ),
name: 'settings.index',
saveScroll: true
},
'/blocked': {
component: require( './routes/settings/blocked/blocked.vue' ),
name: 'settings.blocked'
},
'/feedback': {
component: require( './routes/settings/feedback/feedback.vue' ),
name: 'settings.feedback'
},
'/privacy': {
component: require( './routes/settings/privacy/privacy.vue' ),
name: 'settings.privacy'
},
'/phone': {
component: require( './routes/settings/phone/phone.vue' ),
name: 'settings.phone'
},
'/privacydoc': {
component: require( './routes/static/privacy/privacy.vue' ),
name: 'settings.privacydoc'
},
'/termsdoc': {
component: require( './routes/static/terms/terms.vue' ),
name: 'settings.termsdoc'
},
}
},
'/admin': {
component: require( './routes/admin/admin-comp.vue' ),
subRoutes: {
'/accounts': {
component: require( './routes/admin/accounts/accounts.vue' ),
name: 'admin.accounts',
saveScroll: true
},
'/register': {
component: require( './routes/admin/admin-register/admin-register.vue' ),
name: 'admin.register'
},
'/edit/:uname': {
component: require( './routes/admin/admin-edit/admin-edit.vue' ),
name: 'admin.edit'
}
}
},
'/board': {
component: require( './routes/board/board-comp.vue' ),
name: 'map.board'
}
}
},
} )
So after setting <router-view keep-alive></router-view> in my index.html the map, activities, and contacts routes were kept alive but all other static routes were recycled.
@roblav96 keep-alive and canReuse are completely separate features. keep-alive is implemented by vue, which caches a component when it's detached. canReuse is implemented by vue-router, which decides whether to reuse the router-view component when $route changes.
So keep-alive wasn't designed respect canReuse, nor was it documented. Though the naming may cause some misunderstandings.
Basically, when you set keep-alive on <router-view> in vue-router 0.7, All components that fit in it will be kept alive.
In 2.0 though, it's possible to set whether a route component should use keep-alive https://jsfiddle.net/fnlCtrl/cn5cnsw9/ (though it's not confirmed by Evan)
(and canReuse, among other router hooks and transition object that often causes confusion are removed in vue-router 2.0)
I hope I've answered your question and I'm closing this now ( since it's been inactive for months ). Feel free to ask questions if you have more.
@fnlctrl The jsfiddle page is gone
@fancyboynet Oops.. Since it's simple I'll just put it here:
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"/>
@fnlctrl 谢谢,感觉反过来写是不是会更合理些?
<keep-alive>
<router-view v-if="!$route.meta.notKeepAlive"></router-view>
</keep-alive>
<router-view v-if="$route.meta.notKeepAlive"></router-view>
也可以的,取决于你是需要默认全keep-alive还是默认全不keep-alive了。
very nice , this code solve my problem ! thank u @fnlctrl
@william807803 FYI that approach is obsolete, as in vue 2.1 you can specify what component should be kept alive with <keep-alive>'s include prop. https://gist.github.com/yyx990803/faebe22e8763f5b17572b35ed96f52fe#conditional-keep-alive
So you can just use:
<keep-alive include="foo-component,bar-component">
<router-view></router-view>
</keep-alive>
But of course, the old approach will always work if you'd prefer it.
@fnlctrl
What if i want to "toggle" caching on a component?For example i have a component (e.g foo-component) with all my users in a table.On another component i have a form to insert a new user.How can revaluate caching after insert a new user?
<keep-alive include="foo-component">
<router-view></router-view>
</keep-alive>
This will keep my component cached(foo-component) and will not fetch the new user.On the first example this will keep my component not re-render.
On the previous example this can be achieved by simply add $route.meta.notKeepAlive = true;
So the next time the component(foo-component) has notKeepAlive to false will force to fetch again the users(e.g AJAX request).And then you can set $route.meta.notKeepAlive = false to cache it again.
<keep-alive>
<router-view v-if="!$route.meta.notKeepAlive"></router-view>
</keep-alive>
<router-view v-if="$route.meta.notKeepAlive"></router-view>
I think will be a good idea to have an implementation like the previous example if you have a situation like this one.But how you can achieve the same with include prop?
Thank you
@rousos87 In your case you'd should better use vuex to manage shared state across multiple components, <keep-alive> simply isn't designed for this.
That being said, as for your question
But how you can achieve the same with include prop?
Simply use a dynamic prop:
<keep-alive :include="includedComponents">
<router-view></router-view>
</keep-alive>
Where includedComponents is a dynamic string containing something like foo-component,bar-component
@fnlctrl thanks for the detailed explanation about this matter.
Given your above comments (vuex vs keep-alive), can I conclude that keep-alive is best suited for cases where you want to cached a STATIC component, where you just need to populate once and it will NOT change?
Not exactly. You can use keep-alive on any component, it doesn't matter if its state may change. Keep-alive is meant for reusing previously rendered component (and it's dom nodes) to display it faster.
@rousos87 i have try the following code ..
<keep-alive>
<router-view v-if="!$route.meta.notKeepAlive"></router-view>
</keep-alive>
<router-view v-if="$route.meta.notKeepAlive"></router-view>
$route.meta.notKeepAlive = true turn to $route.meta.notKeepAlive = false;
it caches the route-view ;
but then i turn notKeepAlive to true to disable keepAlive ....it not work......
it is seems that keepAlive will cache component instance .., but no method to clear it ..
do you have any idea ?
Most helpful comment
@fancyboynet Oops.. Since it's simple I'll just put it here: