模仿Vue寫一個mvvm

網絡上有不少教你如何模仿vue手寫mvvm的視頻,我歷來沒有本身動手寫過。這週末想着必定要把這件事情完成。html

下面就關於vue如何實現two-way data-binding作一個簡單的步驟梳理,文字有點多,不過逐步看下去或許會對你們有所啓發哦,同時我也會把須要用到的知識點羅列出來~ vue

所謂雙向綁定,即數據變化 -> 視圖更新;視圖交互變化(如input) -> 數據model變動的效果。node

演示地址react

何爲mvvm?簡言之,把數據和視圖進行關聯的一種模式。這四個字母能夠這麼理解: Model, View, ViewModel。git

模仿vue來寫一個本身的mvvm,往簡單來說,通常涉及下面三個步驟:github

  1. compile -- 模板編譯
  2. observe -- 數據劫持
  3. watcher -- 監聽model的變化,並告知視圖從新編譯,是鏈接compile和observe的橋樑

模板編譯 Compile數組

  1. 用過vue的人都知道,html中有各類v-開頭的指令,也有相似mustache的模板。這部份內容都是要用自定義的data數據進行綁定的。
    所以,模板的編譯就是把你自定義的不管是v-(仍是k-,你隨意~)開頭的指令,仍是mustache,用你想要的data去替換。這是編譯模板最開始須要想到的。
  2. 如何進行編譯,咱們都知道頻繁的操做dom是致使性能低下的一大緣由,相對於拼接字符串沒法操做dom節點來說,把dom放到內存中操做能夠大大提高速度,這就涉及document.createDocumentFragment方法。
    另外,還會要用到諸如appendChild, childNodes, node.attributes, node.textContent, node.nodeType, firstChild等原生js操做dom的方法。
    因爲處理的dom集合都是類數組,因此一個頻繁涉及到的原生js方法是Array.from,把類數組轉化成數組;還有一個高頻方法的是Array.prototype.reduce。
    還須要特別掌握的是,遞歸在項目中的運用。
    在具體處理的代碼中就會考察你的基礎知識啦。因此,光會用vue、react、angular啥的不行哦,就像你光知道這個機器怎麼使用,一旦停電了或機器故障了,你就只能兩手一攤了。
  3. 在內存中處理好以後,再把fragment放回到頁面中便可。至此,頁面最初始的模板編譯完成。

數據劫持 Observe網絡

所謂數據劫持就是當數據(必定是對象,引用類型的值)發生改變的時候,添加咱們本身的邏輯。通常狀況下,咱們給對象賦值都是直接let obj = value,完畢。在這個過程當中咱們沒法添加本身的邏輯,好比你但願當對象的值發生改變時(即監聽對象的變化,當發生改變時調用方法),例如給一個console輸出或作點別的,卻沒法作到。app

那麼如何添加本身的邏輯呢?答案就是ES5的Object.defineProperty方法。在調用Object.defineProperty方法時,若是不指定,configurable,enumerable和writable特性的默認值都是false,因此務必要把configurable和enumerable的值設置成true。最關鍵的是,給對像的某個key寫上get和set方法,這樣一來你就能夠在取值和賦值的過程當中添加本身的邏輯了。dom

監聽(數據)變化 Watcher

這是難點,也是關鍵點。

在Observe觀察到對象數據發生變化了,可是沒法改變視圖(view)。因此,watcher的做用,就是給各個綁定數據的地方,一一對應的進行監聽。在Observe發現數據變化後,調用watcher函數對相應的視圖進行數據更新。

未完待續~

ps.我的認爲單個功能的代碼不超過30行比較好。若是超過了,能夠拆分紅多個細小的代碼塊,方便閱讀,也方便梳理邏輯。

相關文章
相關標籤/搜索