运用Proxy完成双向绑定

媒介:vue3.0要用Proxy来完成双向绑定,因而先来尝试一下完成要领。

1 Object.defineProperty 完成
本来vue2的完成运用Object.defineProperty,监听set,但关于数组直接下标给数组设置值监听不了。

function observe(data) {
  if (!data || typeof data !== 'object') {
      return;
  }
  // 掏出一切属性遍历
  Object.keys(data).forEach(function(key) {
      defineReactive(data, key, data[key]);
  });
};

function defineReactive(data, key, val) {
  observe(val); // 监听子属性
  Object.defineProperty(data, key, {
      enumerable: true, // 可罗列
      configurable: false, // 不能再重写defineProperty
      get: function() {
          return val;
      },
      set: function(newVal) {
          console.log('-------关照定阅者--------')
          val = newVal;
      }
  });
}

2 运用Proxy完成

运用Proxy完成道理主如果new一个Proxy对象,代办你的data值,须要注重的一点是,关于数组的要领操纵来讲,会发生两次赋值操纵,一次是添加值,一次是转变他的length值,而关于Object.defineProperty监听不到的数组下标给数组设置值,Proxy是能够监听到的。

function observe(data) {
    if (!data || typeof data !== 'object') {
        return;
    }
    // 掏出一切属性遍历
    Object.keys(data).forEach(function(_k) {
        // Proxy不允许绑定在非对象上
        if (data[_k] && typeof data[_k] === 'object') {
            data[_k] = defineReactive(data[_k]);
        }
    });
}

function defineReactive(data) {
  return new Proxy(data, {
    set(target, key, value, proxy) {
        // 举行数组操纵时,会举行两次set 一次数据转变,一次length转变,两次转变data的值是稳定,因而不应该多分发一次音讯
      if (
        Object.prototype.toString.call(data) === "[object Array]" &&
        key === "length"
      ) {
        Reflect.set(target, key, value, proxy);
        return true;
      }
      observe(data);
      Reflect.set(target, key, value, proxy);
      console.log('-------关照定阅者--------')
      return true;
    }
  });
    原文作者:fuqihan
    原文地址: https://segmentfault.com/a/1190000018574665
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞