美文网首页
Vue 源码与踩坑

Vue 源码与踩坑

作者: 李霖弢 | 来源:发表于2019-12-26 10:21 被阅读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. 观察者模式 和 发布-订阅者模式

    观察者模式

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

    发布-订阅者模式

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


    相关文章

      网友评论

          本文标题:Vue 源码与踩坑

          本文链接:https://www.haomeiwen.com/subject/gtdkoctx.html