1、beforeDestroy
beforeDestroy周期一般是在组件销毁时调用,比如使用v-if进行组件的显示隐藏,或者页面跳转时就会调用到这个周期。
堆内存使用后一定要注意释放,否则gc总不回收就会导致内存泄漏。
比如对dom的引用、事件Listener、总线eventBus等,一定要在beforeDestroy里释放解绑。
export default {
name:'test',
data(){
return {
width: window.innerWidth,
height: window.innerHeight
}
},
mounted() {
this.resizeFunc = () => {
this.width = window.innerWidth;
this.height = window.innerHeight;
};
window.addEventListener('resize', this.resizeFunc);
},
beforeDestroy(){
window.removeEventListener('resize',this.resizeFunc);
this.resizeFunc = null;
}
}
2、利用weakmap和weakset
当vue中有Dom引用时,需要注意内存释放问题。weakset 和 weakmap对值的引用都是不计入垃圾回收机制的。也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存。
export default {
name: 'test',
data() {
return {
wp: new WeakMap()
}
},
mounted() {
let ele = document.getElementById('con');
let handleFunc = () => {
console.log(ele.innerHTML);//闭包,对ele有引用,不容易释放
}
this.wp.set(ele, handleFunc);//建立节点和事件的关系
ele.addEventListener('click', this.wp.get(ele), false);
},
beforeDestroy() {
this.ele.removeEventListener('click',this.wp.get(this.ele));//清理挂载事件
}
}
3、路由守卫beforeRouteLeave
如果是对router进行了keep-alive,那进行页面跳转时就不会触发beforeDestroy,也就是对组件进行了缓存,不会销毁组件,这时我们可以用路由守卫来确保释放资源。
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
this.$destroy();//手动调用beforeDestroy释放资源,或者单独定义哪些资源需要释放
next(); //允许跳转页面
},
4、移除watch
如果是手动调用监听watch的,也需要释放一下资源。
export default {
data() {
return {
test: 'jack'
}
},
watch: {
test(newVal, oldVal) {
console.log(newVal);
}
},
methods:{
startWatch(){
this.unwatch = this.$watch('test',(newval,oldval)=>{
//this.$watch会返回一个取消监听的函数句柄
console.log('watch>>>',newval);
});
}
},
beforeDestroy() {
// 移除监听
this.unwatch && this.unwatch();//执行销毁监听
}
}
网友评论