vueweb前端

vue防止内存泄漏的几点写法

2022-04-08  本文已影响0人  姜治宇

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();//执行销毁监听
  }
}
上一篇下一篇

猜你喜欢

热点阅读