vue原始碼學習 響應式資料

2021-10-25 15:14:15 字數 3744 閱讀 9130

vue原始碼學習——初始化data

vue原始碼學習——響應式資料

在《vue原始碼學習——初始化data》一文中,知道了在new vue()時做了一系列初始化操作,其中在初始化data資料時,利用observe(data,true)方法,對資料屬性進行了觀察。下面來具體看下是如何對data進行的觀察,從而實現資料驅動~

vue版本:v2.5.21

**如下(src/core/observer/index.js):

export

function

observe

(value: any, asrootdata:

?boolean)

: observer |

void

let ob: observer |

void

// 定義observer例項 並最後返回if(

hasown

(value,

'__ob__'

)&& value.__ob__ instanceof

observer

)elseif(

shouldobserve &&

!isserverrendering()

&&// 判斷是否服務端渲染,node環境

(array.

isarray

(value)

||isplainobject

(value))&&

// 只有當資料物件是陣列或純物件的時候

object.

i***tensible

(value)

&&// 物件可擴充套件 即不是凍結物件等等

!value._isvue //不是vue例項)if

(asrootdata && ob)

return ob

}

**如下(src/core/observer/index.js):

export

class

observer

protoaugment

(value, arraymethods)

// [./array.js] value.__proto__ = arraymethods , 重寫了陣列的7個方法,

}else

this

.observearray

(value)

// 觀察陣列,遍歷陣列,依次觀察各項:observe(items[i])

}else

}

const data =

}

walk

(obj: object)

}

export

function

definereactive

( obj: object,

key: string,

val: any,

customsetter?

:?function,

shallow?

: boolean

)// cater for pre-defined getter/setters

const getter = property && property.

get// 獲取該屬性的訪問器函式(getter)

const setter = property && property.

set// 獲取該屬性的設定器函式(setter)。 如果沒有設定器, 該值為undefinedif(

(!getter || setter)

&& arguments.length ===2)

// !shallow時,observe(val)遞迴呼叫深度監聽

let childob =

!shallow &&

observe

(val)

object.

defineproperty

(obj, key,}}

return value

},set

:function

reactivesetter

(newval)

/* eslint-enable no-self-compare */

if(process.env.

node_env

!=='production'

&& customsetter)

if(getter &&

!setter)

return

// 有getter,沒setter時,為唯讀狀態,不可修改,繼而無需觀察

if(setter)

else

childob =

!shallow &&

observe

(newval)

// `shallow `為false的話,就重新監聽`newval`的值。

dep.

notify()

// 呼叫 dep 例項的 notify 方法, 更新}}

)}

**如下(src/core/observer/dep.js):

let uid =

0// 全域性變數,唯一標識

export

default

class

dep// 新增依賴

addsub

(sub: watcher)

// 移除依賴

removesub

(sub: watcher)

depend()

}// 通知更新,definereactive dep=new dep() ==>setter dep.notify() =>watcher update() ==> ...更新ui

notify()

for(

let i =

0, l = subs.length; i < l; i++)}

}// 這是全域性變數,因為任何時候都可能只有乙個watcher正在評估。

dep.target =

null

const targetstack =

export

function

pushtarget

(target:

?watcher)

export

function

poptarget()

**如下(src/core/observer/watcher.js):

export

default

class

watcher}}

update()

elseif(

this

.sync)

else

}//...

}

每個元件例項都對應乙個 watcher 例項,它會在元件渲染的過程中把「接觸」過的資料 property 記錄為依賴。之後當依賴項的setter 觸發時,會通知 watcher,從而使它關聯的元件重新渲染。

大體流程:

學習 vue 原始碼 響應式原理

由於剛開始學習 vue 原始碼,而且水平有限,有理解或表述的不對的地方,還請不吝指教。vue 主要通過 watcher dep 和 observer 三個類來實現響應式檢視。另外還有乙個 scheduler 來進行排程,本次暫時不做討論。watcher 和 dep 是訂閱者和發布者的關係,每個 wa...

Vue響應式原始碼分析

初始化資料initdata時呼叫obsreve函式。observe函式主要做了3件事 如果不是物件則啥都不做退出。物件已經是響應式的了,有 ob 了,直接返回這個依賴收集器。物件還不是響應式的,執行new observer observer中主要做了3件事 新建乙個new dep 依賴收集器,定義到...

Vue 響應式原理 原始碼

整個函式結束,相當於初始化所有屬性和vue內建事件 如 emit 並且使所有屬性變為響應式。初始化所有option api 對其中的使用者自定義資料data 進行 observe 此函式用來新建乙個類observer的例項,類observer的constructor中用walk 函式進行遍歷每個屬性...