admin管理员组文章数量:1220936
I found an issue in vue-router which triggers me a lot. Always when I switch between my routes, a new instance of the component is created. Further the old instances are not deleted and are running in background!
I would expect that when I open a route, the old components will be destroyed or stop running.
Is there a workaround to fix that issue?
Here is a fiddle: /
let foo = {
template: '<div>Foo</div>',
mounted() {
console.log('Mount Foo with uid: ' + this._uid);
setInterval(() => {console.log('Instance ' + this._uid + ' of Foo is running')}, 500);
}
};
let bar = {
template: '<div>Bar</div>',
mounted() {
console.log('Mount Bar with uid: ' + this._uid);
setInterval(() => {console.log('Instance ' + this._uid + ' of Bar is running')}, 500);
}
};
const router = new VueRouter({
routes: [
{ path: '/user/foo', component: foo },
{ path: '/user/bar', component: bar }
]
});
const app = new Vue({ router }).$mount('#app');
I found an issue in vue-router which triggers me a lot. Always when I switch between my routes, a new instance of the component is created. Further the old instances are not deleted and are running in background!
I would expect that when I open a route, the old components will be destroyed or stop running.
Is there a workaround to fix that issue?
Here is a fiddle: https://jsfiddle.net/4xfa2f19/5885/
let foo = {
template: '<div>Foo</div>',
mounted() {
console.log('Mount Foo with uid: ' + this._uid);
setInterval(() => {console.log('Instance ' + this._uid + ' of Foo is running')}, 500);
}
};
let bar = {
template: '<div>Bar</div>',
mounted() {
console.log('Mount Bar with uid: ' + this._uid);
setInterval(() => {console.log('Instance ' + this._uid + ' of Bar is running')}, 500);
}
};
const router = new VueRouter({
routes: [
{ path: '/user/foo', component: foo },
{ path: '/user/bar', component: bar }
]
});
const app = new Vue({ router }).$mount('#app');
Share
Improve this question
asked Mar 22, 2018 at 9:07
AndrmoelAndrmoel
3023 silver badges12 bronze badges
1
- 1 Possible duplicate of Update VueJs component on route change – Bhojendra Rauniyar Commented Mar 22, 2018 at 9:22
4 Answers
Reset to default 11There are 2 ways to solve this problem:
Properly cleaning up in the destroy
hook
If you use any outside event listeners, like setInterval
, addEventListener
, etc you also need to deregister them when your component gets destroyed, example:
{
name: '...',
template: '...',
data() {
return {
interval: undefined,
timeout: undefined
};
},
mounted() {
interval = setInterval(() => {console.log('Instance ' + this._uid + ' of myself is running')}, 500);
timeout = setTimeout(() => {console.log('Instance ' + this._uid + ' of myself is running')}, 500);
document.addEventListener('click', this.onOutsideClick);
},
beforeDestroy() {
// Cleanup interval
clearInterval(interval);
// Cleanup any pending timeouts
clearTimeout(timeout);
// Cleanup any event listeners outside the root of the element
document.removeEventListener('click', this.onOutsideClick);
},
methods: {
onOutsideClick() {
...
}
}
}
Using keep-alive to keep the component alive
When using keepalive, Vue caches your component, and keeps it alive in the background, this means that only one instance will ever exists. This can potentially consume more memory if you have a large amount of routes
<keep-alive>
<router-view></router-view>
</keep-alive>
Always when I switch between my routes, a new instance of the component is created.
That's expected. you can keep instanes alive and re-use them with the <keep-alive>
component, but that's usually not necessary and if so, requires special attention to re-initiate all local state of re-used components where necesseray.
Creating a fresh instance is much cleaner and therefore the default behaviour.
Further the old instances are not deleted and are running in background!
That's not expected. Previous instances are destroyed.
setInterval(() => {console.log('Instance ' + this._uid + ' of Foo is running')}, 500);
Well, since this intervall callback contains a reference to the component instance, it can't be garbage collected by the browser, So you are keeping them alive, not Vue.
Without that intervall, I woudl expect the instance to be garbage collected after the router destroyed them.
The same issue is stated here : https://github.com/vuejs/vuex/issues/1580
As a workaround you can use transition mode out-in. Rolandoda
<transition mode="out-in"> <router-view></router-view> </transition>
In Vue 3, the syntax has changed. The solution to tell Vue Router to keep all the components alive is:
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
If you only want to keep a certain one alive, then you can use this:
<router-view v-slot="{ Component }">
<keep-alive include="foo">
<component :is="Component" />
</keep-alive>
</router-view>
Or make sure one isn't kept alive (but all others are), do this:
<router-view v-slot="{ Component }">
<keep-alive exclude="foo">
<component :is="Component" />
</keep-alive>
</router-view>
本文标签: javascriptvuerouter creates always a new Component instanceStack Overflow
版权声明:本文标题:javascript - vue-router creates always a new Component instance - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1739312928a2157667.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论