Vue 源码与踩坑

2019-12-26  本文已影响0人  李霖弢

1. data属性为什么使用了_或$开头却会提示报错?

vue采用了defineProperty实现数据驱动视图,此时数据均挂载在$data_data上,要想让数据能直接被this访问,还做了如下处理

// target是vue实例,key为_data,这样就能通过访问this.xxx = this._data.xxx了
function proxy (target, sourceKey, key) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  };
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val;
  };
  Object.defineProperty(target, key, sharedPropertyDefinition);
}

此时有如下检测,当属性以_$开头时不会调用proxy方法,因此只能通过_data.属性名$data.属性名访问

function initData (vm) {
  var data = vm.$options.data;
  data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {};
  if (!isPlainObject(data)) {
    data = {};
    process.env.NODE_ENV !== 'production' && warn(
      'data functions should return an object:\n' +
      'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
      vm
    );
  }
  // proxy data on instance
  var keys = Object.keys(data);
  var props = vm.$options.props;
  var methods = vm.$options.methods;
  var i = keys.length;
  while (i--) {
    var key = keys[i];
    if (process.env.NODE_ENV !== 'production') {
      if (methods && hasOwn(methods, key)) {
        warn(
          ("Method \"" + key + "\" has already been defined as a data property."),
          vm
        );
      }
    }
    if (props && hasOwn(props, key)) {
      process.env.NODE_ENV !== 'production' && warn(
        "The data property \"" + key + "\" is already declared as a prop. " +
        "Use prop default value instead.",
        vm
      );
    } else if (!isReserved(key)) {
        // 这边处理代理,所以isReserved处理了是否要进行代理
      proxy(vm, "_data", key);
    }
  }
  // observe data
  observe(data, true /* asRootData */);

  function isReserved (str) {
      var c = (str + '').charCodeAt(0);
      return c === 0x24 || c === 0x5F // 这边判断chartCode是否为_和$
   }
}

2. 观察者模式 和 发布-订阅者模式

观察者模式

被观察者中记录注册到其的观察者,每当被观察者触发变化时,主动驱动观察者的方法

发布-订阅者模式

订阅者把自己想订阅的事件注册到调度中心,当发布者触发变化时,将事件推送给调度中心,调度中心找到订阅该事件的订阅者,并驱动其方法


上一篇下一篇

猜你喜欢

热点阅读