Vue原始碼解析 實現觀察者OBserver

2022-04-29 14:06:07 字數 2748 閱讀 7766

vue採用資料劫持配合訂閱者和發布者模式的方式 ,

通過   object.defineproperty 的setter 和  getter  對資料進行劫持 , 

在資料變化時, 發布訊息給依賴器 dep(訂閱者),  去通知觀察者watcher  做出對應的**函式 , 進行檢視更新

mvvm 作為繫結入口 , 整合observer , compile 和watcher  三者 , observer來監聽model資料變化 , 

compile來解析編譯模板指令 , 最終利用watcher 搭建起 compile , observer , watcher 之間的通訊橋梁 , 

達到資料 變化=>  檢視更新 ; 檢視互動變化 => 資料model變更的雙向繫結效果 

observer.js

class watcher 

getoldval()

updata()

}}class dep

//收集觀察者

addsub(watcher)

//通知觀察者去更新

notify()

}class observer

observer(data) )}}

definerective(obj, key, value) ,

set: (newval) =>

//更改資料後 通知觀察者更新

dep.notify()}})

}}

1. 初始化資料時 , 劫持所有屬性  走observer中  object.defineproperty 的get方法   通知訂閱者dep去收集每個屬性上繫結的觀察者watcher  , 通過dep.addsub  存放 subs 中 

2.更改資料時 , 觸發observer 中object.defineproperty 的set方法   ,  此時 通知訂閱者dep , 資料有變化 ,  訂閱者通過   dep.notify()  ,  對存在subs 陣列中屬性繫結的觀察者watcher進行遍歷 並觸發watcher.updata進行檢視更新

需要注意:

1. 何時在所有屬性上繫結觀察者wacther ?

當初始化頁面 , 解析指令渲染頁面前 , 對不同指令模板的所有屬性分別新增watcher

並在  observer    中 object.defineproperty 的get方法中往收集依賴器中存放wacther

2.何時往dep中新增觀察者 , 並能獲取到資料變化的屬性上繫結的wacther?

通過   dep.target = this 來獲取 wacther 並在資料變化後對之前的wacther進行銷毀  dep.target = null

避免不斷新增wacther , 不易維護

結合   vue原始碼解析--實現乙個指令解析器 compile 基礎上在解析指令渲染檢視時新增觀察者 並實現

proxy**  和 input  檢視驅動資料

mvue.js

const compileutil =, vm.$data)

},setval(expr, vm, inputval) , vm.$data)

},getcontentval(expr, vm) \}/g, (...args) =>)

},text(node, expr, vm) \}/g, (...args) =>)

return

this.getval(args[1], vm);

})}

else

this

.updater.textupdater(node, value)

},html(node, expr, vm) )

this

.updater.htmlupdater(node, value)

},model(node, expr, vm) )

//檢視=>資料 =>檢視

node.addeventlistener('input', (e) =>)

this

.updater.modelupdater(node, value)

},on(node, expr, vm, eventname) ,

updater: ,

htmlupdater(node, value) ,

modelupdater(node, value)

}}class complie

compile(fragment)

else

if (child.childnodes && child.childnodes.length > 0) })}

compileelement(node) =attr;

if (this.isdirective(name))

else

if (this.iseventname(name)) })}

compiletext(node) \}/.test(content))

}node2fragment(node)

return

f; }

iselementnode(el)

isdirective(attrname)

iseventname(attrname)

}class mvue

}proxydata(data) ,

set() })}

}}

觀察者模式之EventBus原始碼解析

1 觀察者模式概述 觀察者模式 observer pattern 定義物件之間的一種一對多依賴關係,使得每當乙個物件狀態發生改變時,其相關依賴物件皆得到通知並自動更新。觀察者模式的別名包括發布 訂閱 publish subscribe 模式 模型 檢視 model view 模式。觀察者模式是一種物...

手寫vue原始碼 精簡版) 觀察者

observer觀察的物件 observer實際是對data進行觀察,從而達到第2點中的目的 observer的目的 observer的目的有兩個。其一,依賴收集,其二,更新顯示 observer實現原理 observer跟資料 一樣,是通過object.defineproperty 來實現的 具體...

junit原始碼學習 觀察者模式

testresult擔任發布者角色,擁有protected listflisteners 擔任觀察者角色 以下都是testresult類原始碼 registers a testlistener觀察者註冊 public synchronized void addlistener testlistene...