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 函式進行遍歷每個屬性...