JS框架雙向資料繫結原理及思考

2021-08-21 23:53:57 字數 1746 閱讀 7215

雙向資料繫結原理(vue)

如何設計搭建自己的框架

**暫略,詳見,github [位址]

單向指是資料從model流向view

雙向是在單向的基礎上資料再從view 流向model。

簡單的說是這樣的,

初次模板與資料渲染時,監聽資料每個屬性的每次呼叫(通過getter實現),並給其屬性新增觀察者。監聽資料的每個屬性變更(通過setter實現),並通知與其相關的觀察者,觀察者呼叫自身的更新方法更新view。掃瞄模板時,找到雙向繫結指令,並綁上指定事件,事件觸發後更新資料,資料更新觸發單向繫結邏輯 view  更新。

說的太簡單很多人對細節不清楚,說的細了就是後面的長篇大論了。

相信很多人的疑問有像下面這些的:

觀察者只是抽象概念,

它具體實現是什麼?

為什麼同乙個屬性不只乙個觀察者?

又在什麼時候新增的?

觀察者新增到哪了?

每個觀察者的更新方法又是怎麼確定的?

單向、雙向資料繫結是如何實現的呢?假如現在要寫乙個雙向繫結框架要如何設計呢?

單向資料繫結需求可以簡單的抽象為:將資料和模板進行某種繫結,資料中的某個屬性值發生變化時,屬性對應的模板和新值進行處理更新ui(移除舊的ui插入新的ui)。

通過上面的簡單分析,就可以發現"模板"相關需求需要用節點操作來實現,因為需要給特定元素繫結事件,要處理元素中的指令,必定要對模板中每乙個節點進行遍歷,並對每個節點的屬性進行遍歷。

下面會逐步分析需求,再將每個需求再細化就可以得到完整的需求,最後實現這些需求。

將資料的每乙個屬性與相對應的模板建立聯絡,資料屬性值變更時view進行更新

將特定元素的指定事件回饋到資料,資料被修改,同時與些資料相關view更新

【1.1解決思路】

資料屬性的讀寫可以通過設定getter setter實現,通過object.defineproperty()方法設定。 寫乙個方法遞迴的處理資料的每個屬性不是什麼難事。**暫略,詳見,github [位址]

【1.2解決思路】

我們需要乙個compiler 對模板的每乙個節點進行掃瞄分析,分板當前節點是否有指令(插值表示式、單向資料繫結、雙向資料繫結,事件繫結等)。如果有指令,找到當前指令相關的資料屬性,當前節點即為'模板'(ps:資料更新時更樣的節點)。

【1.3解決思路】

當compiler 對節點分析時如果找到指令,則給該指令相關的屬性的更新列表,新增乙個watcher例項,該例項包含渲染相關『模板』(ps:當前掃瞄到的節點) 

【1.4解決思路】

在1.1中對所有資料屬性進行監聽時,為每乙個屬性掛載乙個物件(實際上是閉包),該物件擁有乙個notify方法,還擁有乙個值為陣列的list 屬性,list 中存放的是當前屬性相關的 watcher例項,該例項在1.3(模板解析) 時生成並新增進來,該例項擁有乙個update 方法,用來更新view; 當屬性值變化時,呼叫相關必包中的notify 方法,該方法遍歷list 中的每乙個watcher 例項,並呼叫該例項的update 方法,upadate方法會在1.3(模板解析)時根據指令生成相關update 方法。本demo 中閉包物件是watcher 類來構造,也可以分開。

以上只是粗枝大葉的整個邏輯分析,細節還有很多,比如:指令解析,管道符解析,指令表示式解析,插槽(用以標記更新時插入點),需要銷毀節點等,後續整理出來,計畫搞乙個系列文章,比如模板指令解析如何進行等,本demo 也有點粗造有時間吧整理一下,以後像虛擬dom的可以搞一搞,像生命週期鉤子有了大框架要加也不是很困難,等以後細化再更新。

因精力有限。。。今日到此(未完待續)

資料雙向繫結原理

angularjs 採用 髒值檢測 的方式 資料發生變更後,對於所有的資料和檢視的繫結關係進行一次檢測,識別是否有資料發生了改變,有變化進行處理,可能進一步引發其他資料的改變,所以這個過程可能會迴圈幾次,一直到不再有資料變化發生後,將變更的資料傳送到檢視,更新頁面展現。如果是手動viewmodel ...

雙向資料繫結原理

資料劫持 vuejs 則使用 es5 提供的 object.defineproperty 方法,監控對資料的操作,從而可以自動觸發資料同步。並且,由於是在不同的資料上觸發同步,可以精確的將變更傳送給繫結的檢視,而不是對所有的資料都執行一次檢測。var obj object.definepropert...

深度挖掘vue及雙向資料繫結原理

本文簡單模擬vue的實現過程以及雙向資料繫結的原理,雙綁原理在面試時基本上是逃不過的問題。接下來直接上 新建index.html檔案 呵呵噠 新建yvue.js檔案 new yvue class yvue obverse value 遍歷該物件 object.keys value foreach k...