【Vue】为什么Vue3使用Proxy代替defineProperty?

先来看看 Vue2 中 defineProperty 来操作数据:

const obj = {
  a: 1,
  b: 2,
  c: {
    a: 1,
    b: 2
  }
}
function _isObject(v) {
  return typeof v === 'object' && v !== null;
}
function observe(object) {
  for (let key in object) {
    let v = object[key];
    if (_isObject(v)) {
      observe(v)
    }
    Object.defineProperty(object, key, {
      get() {
        console.log('read ' + key);
        return v;
      },
      set(val) {
        if (val !== v) {
          console.log('change ' + key);
          v = val;
        }
      }
    })
  }
}
observe(obj)
// obj.a = 3;
obj.c.a = 4;

所以 Vue2 的缺陷是无法监听到属性的增加和删除,因为只有 getter 和 setter 函数。此外,还通过深度遍历,有效率的损失,将属性变成 getter 和 setter 函数。

而 Vue3 中Proxy 直接监听整个对象的变化:

const obj = {
  a: 1,
  b: 2,
  c: {
    a: 1,
    b: 2
  }
}
function _isObject(v) {
  return typeof v === 'object' && v !== null;
}
function observe(obj) {
  const proxy = new Proxy(obj, {
    get(target, k) {
      let v = target[k]
      if (_isObject(v)) {
        v = observe(v);
      }
      console.log('read', k)
      return v;
    },
    set(target, k, val) {
      if (target[k] !== val) {
        target[k] = val;
        console.log('change', k)
      }
    }
    // ....

  })
  return proxy;
}

proxy.a = 3;
proxy.aa;

不监听属性,而是监听整个代理对象。只有当读取到对象属性的时候才会进行遍历监听。

你可能感兴趣的:(Vue,vue.js,javascript,前端)