• 7.4 initData

    7.4 initData

    data在初始化选项合并时会生成一个函数,只有在执行函数时才会返回真正的数据,所以initData方法会先执行拿到组件的data数据,并且会对对象每个属性的命名进行校验,保证不能和props,methods重复。最后的核心方法是observe,observe方法是将数据对象标记为响应式对象,并对对象的每个属性进行响应式处理。与此同时,和props的代理处理方式一样,proxy会对data做一层代理,直接通过vm.XXX可以代理访问到vm._data上挂载的对象属性。

    1. function initData(vm) {
    2. var data = vm.$options.data;
    3. // 根实例时,data是一个对象,子组件的data是一个函数,其中getData会调用函数返回data对象
    4. data = vm._data = typeof data === 'function'? getData(data, vm): data || {};
    5. var keys = Object.keys(data);
    6. var props = vm.$options.props;
    7. var methods = vm.$options.methods;
    8. var i = keys.length;
    9. while (i--) {
    10. var key = keys[i];
    11. {
    12. // 命名不能和方法重复
    13. if (methods && hasOwn(methods, key)) {
    14. warn(("Method \"" + key + "\" has already been defined as a data property."),vm);
    15. }
    16. }
    17. // 命名不能和props重复
    18. if (props && hasOwn(props, key)) {
    19. warn("The data property \"" + key + "\" is already declared as a prop. " + "Use prop default value instead.",vm);
    20. } else if (!isReserved(key)) {
    21. // 数据代理,用户可直接通过vm实例返回data数据
    22. proxy(vm, "_data", key);
    23. }
    24. }
    25. // observe data
    26. observe(data, true /* asRootData */);
    27. }

    最后讲讲observe,observe具体的行为是将数据对象添加一个不可枚举的属性__ob__,标志对象是一个响应式对象,并且拿到每个对象的属性值,重写getter,setter方法,使得每个属性值都是响应式数据。详细的代码我们后面分析。