- 7.4 initData
7.4 initData
data在初始化选项合并时会生成一个函数,只有在执行函数时才会返回真正的数据,所以initData方法会先执行拿到组件的data数据,并且会对对象每个属性的命名进行校验,保证不能和props,methods重复。最后的核心方法是observe,observe方法是将数据对象标记为响应式对象,并对对象的每个属性进行响应式处理。与此同时,和props的代理处理方式一样,proxy会对data做一层代理,直接通过vm.XXX可以代理访问到vm._data上挂载的对象属性。
function initData(vm) {var data = vm.$options.data;// 根实例时,data是一个对象,子组件的data是一个函数,其中getData会调用函数返回data对象data = vm._data = typeof data === 'function'? getData(data, vm): data || {};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 (methods && hasOwn(methods, key)) {warn(("Method \"" + key + "\" has already been defined as a data property."),vm);}}// 命名不能和props重复if (props && hasOwn(props, key)) {warn("The data property \"" + key + "\" is already declared as a prop. " + "Use prop default value instead.",vm);} else if (!isReserved(key)) {// 数据代理,用户可直接通过vm实例返回data数据proxy(vm, "_data", key);}}// observe dataobserve(data, true /* asRootData */);}
最后讲讲observe,observe具体的行为是将数据对象添加一个不可枚举的属性__ob__,标志对象是一个响应式对象,并且拿到每个对象的属性值,重写getter,setter方法,使得每个属性值都是响应式数据。详细的代码我们后面分析。
