Vue实例在建立的时候会运行一系列的初始化操作,而在这些初始化操作里面,和数据绑定关联最大的是initState。
首先,来看一下他的代码:
函数initState (vm) { vm。_watchers=[]; var选择=vm。美元选项; 如果(opts.props) { initProps (vm, opts.props);//初始化道具 } 如果(opts.methods) { initMethods (vm, opts.methods);//初始化方法 } 如果(opts.data) { initData (vm);//初始化数据 其他}{ 观察(vm。_data=https://www.yisu.com/zixun/{}, true/* asRootData */); } 如果(opts.computed) { initComputed (vm, opts.computed);//初始化计算 } 如果选择。& &选择观看。看!==nativeWatch) { initWatch (vm, opts.watch);//初始化的手表 } }
在这么多的数据的初始化中,道具、方法和数据是比较简单的(所以我就不详细介绍了& # 9786;),而计算和观察则相对较难,逻辑较复杂,所以我下面主要讲下计算和观察(以下代码部分为简化后的)。
initState里面主要是对vue实例中的道具、方法、数据、计算和观察数据进行初始化。
在初始化道具的时候(initProps),会遍历道具中的每个属性,然后进行类型验证,数据监测等(提供为道具属性赋值就抛出警告的钩子函数)。
在初始化方法的时候(initMethods),主要是监测方法中的方法名是否合法。
在初始化数据的时候(initData),会运行观察函数深度遍历数据中的每一个属性,进行数据劫持。
在初始化计算的时候(initComputed),会监测数据是否已经存在数据或道具上,如果存在则抛出警告,否则调用defineComputed函数,监听数据,为组件中的属性绑定getter及setter。如果计算中属性的值是一个函数,则默认为属性的getter函数。此外属性的值还可以是一个对象,他只有三个有效字段集,得到和缓存,分别表示属性的setter, getter和是否启用缓存,其中得到是必须的,缓存默认为真的。
计算函数initComputed (vm) { var观察家=vm。_computedWatchers=Object.create(空); (在计算var关键){ var userDef=计算(例子); var getter=typeof userDef===δ堋? # 63;userDef: userDef.get;//创建一个计算属性观察者 观察者(例子)=新观察家( 虚拟机, getter | |等待, 等待, computedWatcherOptions ); 如果(!(关键在vm)) {//如果定义的计算属性不在组件实例上,对属性进行数据劫持//defineComputed很重要,下面我们再说 defineComputed (vm、关键、userDef); 其他}{//如果定义的计算属性在数据和道具有抛出警告 } } }
在初始化看的时候(initWatch),会调用<代码> vm。美元看代码>函数为表中的属性绑定setter回调(如果组件中没有该属性则不能成功监听,属性必须存在于道具、数据或计算中)。如果表中属性的值是一个函数,则默认为属性的setter回调函数,如果属性的值是一个数组,则遍历数组中的内容,分别为属性绑定回调,此外属性的值还可以是一个对象,此时,对象中字的处理程序段代表setter回调函数,直接代表是否立即先去执行里面的处理方法,深代表是否深度监听。
<代码> vm。美元看代码>函数会直接使用观察者构建观察者对象.watch中属性的值作为watcher.cb存在,在观察者更新的时候,在watcher.run函数中执行。想了解这一过程可以看我上一篇的vue响应式系统,观察观察家,dep中关于观察者的介绍。
函数initWatch (vm,观察){//遍历表,为每一个属性创建侦听器 (var关键看){ var处理程序=看(例子);//如果属性值是一个数组,则遍历数组,为属性创建多个侦听器//createWatcher函数中封装了vm。美元的手表,会在vm。观察中美元创建侦听器 如果(Array.isArray(处理器)){ (var=0;我& lt;handler.length;我+ +){ createWatcher (vm,关键,处理程序[我]); } 其他}{//为属性创建侦听器 createWatcher (vm,关键,处理程序); } } } 函数createWatcher (vm, expOrFn、处理程序、期权){//如果属性值是一个对象,则取对象的处理程序属性作为回调 如果(isPlainObject(处理器)){ 选择=处理程序; 处理程序=handler.handler; }//如果属性值是一个字符串,则从组件实例上寻找 如果(typeof处理程序==='字符串'){ 处理程序=vm(处理器); }//为属性创建侦听器 返回vm。看美元(expOrFn、处理程序、期权) }vue数据初始化initState的实例详解