vue props原理

作者: 努力学习的小丸子 | 来源:发表于2020-04-25 22:03 被阅读0次

结论

1、props传值基本类型,在父子组件中,数据都是响应式的。在子组件中改变props属性的值,不会影响父组件。父组件中的改变会影响子组件。
2、props传值引用类型(如对象),在父组件中,会对该对象的所有属性进行拦截,而在子组件中,只会拦截最上层的属性。所以如果在子组件中修改对象的属性,父组件中的值会更新。父组件中的改变同样会影响子组件。但是如果直接替换掉整个对象,则父组件中的数据不会发生改变,如果直接替换整个对象,vue会抛出错误Avoid mutating a prop directly
3、在父组件中改变对应的data,子组件中的值也会改变。之所以要在子组件中再对props的数据用watch进行监听,是需要在数据变化时做一些操作。不如如果props中的值是在echarts中使用的话,数据改变不会自动刷新图表,所以需要监听,这样就知道什么去刷新图表。

过程描述

在created函数调用之前,调用了initProps方法,该方法会遍历vm.$options.propsData对象,然后使用Object.defineProperty拦截所有的key。
第一步 两个关键的步骤,
1、拦截属性的get/set,调用 defineReactive$$1传了四个参数,所以才不会拦截对象的属性。详见第二步的方法。
2、使用proxy进行访问转接,所以我们能使用this.xx直接访问到this. vm._props.xx

 function initProps (vm, propsOptions) {
    var propsData = vm.$options.propsData || {};
    var props = vm._props = {};
        defineReactive$$1(props, key, value, function () {
          if (!isRoot && !isUpdatingChildComponent) {
          //错误提示代码
          }
        });
      }
      if (!(key in vm)) {
        proxy(vm, "_props", key);
      }
    };

  }

第二步

function defineReactive$$1 (
    obj,
    key,
    val,
    customSetter,
    shallow
  ) {
    var dep = new Dep();
    var property = Object.getOwnPropertyDescriptor(obj, key);
    //在initData和initProps方法中,调用defineReactive$$1方法传的参数不一样
    //从而影响val值,最终影响是否调用observe(val)方法
    //在initData中传入的参数是2个,会调用observe(val)方法,从而实现对象的深度监听
    //在initProp中,不会调用observe(val),所以不会监听对象的属性
    if ((!getter || setter) && arguments.length === 2) {
      val = obj[key];
    }
    var childOb = !shallow && observe(val);
    Object.defineProperty(obj, key, {
      get: function reactiveGetter () {
        if (Dep.target) {
          dep.depend();
//props属性队形的childOb为false
          if (childOb) {
            childOb.dep.depend();
            if (Array.isArray(value)) {
              dependArray(value);
            }
          }
        }
        return value
      },
      set: function reactiveSetter (newVal) {
      //省略其他代码
        dep.notify();
      }
    });
  }

相关文章

网友评论

    本文标题:vue props原理

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