设计模式(5): vue 不监听绑定的变量

概述

最近最近做项目的时候总会思考一些大的应用设计模式相关的问题,我把自己的思考记录下来,供以后开发时参考,相信对其他人也有用。

绑定变量

一般情况下,如果我们需要在组件中使用某个变量,会这么使用:

data() {
  return {
    myData: [],
  };
}

如果这个变量是外部变量,例如从外部文件引入的话,就会这么使用:

import { provinces } from '@/util/consts';

export default {
  data() {
    return {
      myData: provices,
    };
  },
}

问题

但是如果这个变量是一个嵌套层级很深,数据量很大的对象的话,如果按照上面那样使用,vue 就会去遍历这个变量的所有属性,来监听这个变量的变化。非常的消耗性能,一个典型的例子是:

export default {
  data() {
    return {
      bannerBg: null,
    };
  },
  mounted() {
    this.loadScript('/js/three.min.js', () => {
      this.loadScript('/js/vanta.net.min.js', () => {
        this.bannerBg = window.VANTA.NET({
          el: '#bannerBg',
          color: 0x2197F3,
          backgroundColor: 0x071E31,
        });
      });
    });
  },
  beforeDestroy() {
    this.bannerBg.destroy();
  },
  methods: {
    loadScript(path, callback) {
      const script = document.createElement('script');
      script.src = path;
      script.language = 'JavaScript';
      script.onload = () => callback();
      document.body.appendChild(script);
    },
  },
}

上面的例子中,我们为了避免内存泄漏,在 beforeDestroy 生命周期里面进行回收,而为了获取回收的变量,我们把它绑定给了 this.bannerBg。

但是事实是,我们并不需要监听 this.bannerBg 这个变量,而这么绑定的结果是,这个 vue 组件在 mounted 的时候需要遍历 this.bannerBg 来增加 vue 的监听属性,非常消耗性能

解决方案

所以,我们建议不把 bannerBg 放到 data() 里面去监听,而是**直接绑定给 this **就行了。优化后的代码如下:

export default {
  mounted() {
    this.loadScript('/js/three.min.js', () => {
      this.loadScript('/js/vanta.net.min.js', () => {
        this.bannerBg = window.VANTA.NET({
          el: '#bannerBg',
          color: 0x2197F3,
          backgroundColor: 0x071E31,
        });
      });
    });
  },
  beforeDestroy() {
    this.bannerBg.destroy();
  },
  methods: {
    loadScript(path, callback) {
      const script = document.createElement('script');
      script.src = path;
      script.language = 'JavaScript';
      script.onload = () => callback();
      document.body.appendChild(script);
    },
  },
}

如果这个变量不是过程中生成的,而是初始化的时候生成的,我们建议在 data() 方法里面这么做:

import { provinces } from '@/util/consts';

export default {
  data() {
    this.myData = provices;

    return {
      // 移到上面去了
      // myData: provices,
    };
  },
}
原文地址:https://www.cnblogs.com/yangzhou33/p/11470486.html