Observer 数据响应分为Observer
和Watcher
两个核心部分组成
根据之前的分析可知,Vue
是在_init
方法中的initState(vm)
完成对数据观测
接着找到这个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export function initState (vm : Component ) { vm._watchers = [] const opts = vm.$options if (opts.props ) initProps (vm, opts.props ) if (opts.methods ) initMethods (vm, opts.methods ) if (opts.data ) { initData (vm) } else { observe (vm._data = {}, true ) } if (opts.computed ) initComputed (vm, opts.computed ) if (opts.watch && opts.watch !== nativeWatch) { initWatch (vm, opts.watch ) } }
先忽略上面,先看 initData(vm)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 function initData (vm : Component ) { let data = vm.$options .data data = vm._data = typeof data === 'function' ? getData (data, vm) : data || {} if (!isPlainObject (data)) { data = {} } const keys = Object .keys (data) let i = keys.length while (i--) { const key = keys[i] if (!isReserved (key)) { proxy (vm, `_data` , key) } } observe (data, true ) } export function getData (data : Function , vm : Component ): any { pushTarget () try { return data.call (vm, vm) } catch (e) { handleError (e, vm, `data()` ) return {} } finally { popTarget () } }
除开最后一行,实际上是做了一些数据初始化、清空Dep对象和_data数据代理的的工作,接着往下看 observe(data, true /* asRootData */)
1 2 3 4 5 6 7 8 9 10 11 export function observe (value : any, asRootData : ?boolean): Observer | void { ob = new Observer (value) return ob }
接着找到 Observer
类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 export class Observer { value : any; dep : Dep ; vmCount : number; constructor (value : any) { this .value = value this .dep = new Dep () this .vmCount = 0 def (value, '__ob__' , this ) if (Array .isArray (value)) { if (hasProto) { protoAugment (value, arrayMethods) } else { copyAugment (value, arrayMethods, arrayKeys) } this .observeArray (value) } else { this .walk (value) } } walk (obj : Object ) { const keys = Object .keys (obj) for (let i = 0 ; i < keys.length ; i++) { defineReactive (obj, keys[i]) } } observeArray (items : Array <any>) { for (let i = 0 , l = items.length ; i < l; i++) { observe (items[i]) } } }
由上面可知,如果对象类型,直接对所有的key
执行defineReactive
方法,数组则通过劫持数组原型上的方法进行观测
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 import { def } from '../util/index' const arrayProto = Array .prototype export const arrayMethods = Object .create (arrayProto)const methodsToPatch = [ 'push' , 'pop' , 'shift' , 'unshift' , 'splice' , 'sort' , 'reverse' ] methodsToPatch.forEach (function (method ) { const original = arrayProto[method] def (arrayMethods, method, function mutator (...args) { const result = original.apply (this , args) const ob = this .__ob__ let inserted switch (method) { case 'push' : case 'unshift' : inserted = args break case 'splice' : inserted = args.slice (2 ) break } if (inserted) ob.observeArray (inserted) ob.dep .notify () return result }) })
接着来看最重要的defineReactive
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 export function defineReactive ( obj : Object , key : string, val : any, customSetter?: ?Function , shallow?: boolean ) { const dep = new Dep () const property = Object .getOwnPropertyDescriptor (obj, key) if (property && property.configurable === false ) { return } const getter = property && property.get const setter = property && property.set if ((!getter || setter) && arguments .length === 2 ) { val = obj[key] } let childOb = !shallow && observe (val) Object .defineProperty (obj, key, { enumerable : true , configurable : true , get : function reactiveGetter () { const value = getter ? getter.call (obj) : val if (Dep .target ) { dep.depend () if (childOb) { childOb.dep .depend () if (Array .isArray (value)) { dependArray (value) } } } return value }, set : function reactiveSetter (newVal) { const value = getter ? getter.call (obj) : val if (newVal === value || (newVal !== newVal && value !== value)) { return } if (getter && !setter) return if (setter) { setter.call (obj, newVal) } else { val = newVal } childOb = !shallow && observe (newVal) dep.notify () } }) }
Observer
通过 getter/setter
监听数据的读写。在getter
中收集依赖,在setter
中通知依赖更新