介紹
observer是Vue核心中最重要的一個模塊(個人認為),能夠實現視圖與數據的響應式更新,底層全憑observer的支持。
注意:本文是針對Vue@2.1.8進行分析
observer模塊在Vue項目中的代碼位置是src/core/observer,模塊共分為這幾個部分:
示意圖如下:

Observer
Observer類定義在src/core/observer/index.js中,先來看一下Observer的構造函數
constructor (value: any) {
this.value = value
this.dep = new Dep()
this.vmCount = 0
def(value, '__ob__', this)
if (Array.isArray(value)) {
const augment = hasProto
? protoAugment
: copyAugment
augment(value, arrayMethods, arrayKeys)
this.observeArray(value)
} else {
this.walk(value)
}
}
value是需要被觀察的數據對象,在構造函數中,會給value增加__ob__屬性,作為數據已經被Observer觀察的標志。如果value是數組,就使用observeArray遍歷value,對value中每一個元素調用observe分別進行觀察。如果value是對象,則使用walk遍歷value上每個key,對每個key調用defineReactive來獲得該key的set/get控制權。
解釋下上面用到的幾個函數的功能:
如果不太理解上面的文字描述可以看一下圖:

Dep
Dep是Observer與Watcher之間的紐帶,也可以認為Dep是服務于Observer的訂閱系統。Watcher訂閱某個Observer的Dep,當Observer觀察的數據發生變化時,通過Dep通知各個已經訂閱的Watcher。
Dep提供了幾個接口:
Watcher
Watcher是用來訂閱數據的變化的并執行相應操作(例如更新視圖)的。Watcher的構造器函數定義如下:
constructor (vm, expOrFn, cb, options) {
this.vm = vm
vm._watchers.push(this)
// options
if (options) {
this.deep = !!options.deep
this.user = !!options.user
this.lazy = !!options.lazy
this.sync = !!options.sync
} else {
this.deep = this.user = this.lazy = this.sync = false
}
this.cb = cb
this.id = ++uid // uid for batching
this.active = true
this.dirty = this.lazy // for lazy watchers
this.deps = []
this.newDeps = []
this.depIds = new Set()
this.newDepIds = new Set()
this.expression = process.env.NODE_ENV !== 'production'
? expOrFn.toString()
: ''
if (typeof expOrFn === 'function') {
this.getter = expOrFn
} else {
this.getter = parsePath(expOrFn)
if (!this.getter) {
this.getter = function () {}
process.env.NODE_ENV !== 'production' && warn(
`Failed watching path: "${expOrFn}" ` +
'Watcher only accepts simple dot-delimited paths. ' +
'For full control, use a function instead.',
vm
)
}
}
this.value = this.lazy
? undefined
: this.get()
}
參數中,vm表示組件實例,expOrFn表示要訂閱的數據字段(字符串表示,例如a.b.c)或是一個要執行的函數,cb表示watcher運行后的回調函數,options是選項對象,包含deep、user、lazy等配置。
watcher實例上有這些方法:
Array methods
在src/core/observer/array.js中,Vue框架對數組的push、pop、shift、unshift、sort、splice、reverse方法進行了改造,在調用數組的這些方法時,自動觸發dep.notify(),解決了調用這些函數改變數組后無法觸發更新的問題。
在Vue的官方文檔中對這個也有說明:http://cn.vuejs.org/v2/guide/list.html#變異方法
總結
以上就是這篇文中的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。