mvvm與virtual dom算法的實踐——“hoz”

近來筆者盤算本身造一個輪子,寫一個mvvm的庫,磨鍊本身的才能,畢竟用庫誰都可以,然則開闢庫的才能不是誰都有,不過筆者不是什麼大神,所以更多的是願望在這個過程當中學到東西,然後這個庫不只是完成一個響應式數據綁定這麼簡樸,那末這個庫有什麼特性呢?請往下看。
固然這個庫還處在剛剛開始階段,功用完成的比較簡樸,在此發表出來,迎接人人藉此為基本一同去完美它。項目地點:Hoz.js,迎接人人start,fork,以及提issues。

特性

  • 自創redux,flux等的頭腦,引入狀況治理
  • 引入virtual dom,diff 算法,進步機能

聲明式語法

  <div id = "app">
      <div>
          <img src="{{moveImage}}" />
          <p>{{moveName}}</p>
      </div>
  </div>
var hoz = new Hoz('app', state, changeStore)

var state = {
  moveName: '',
  moveImage: ''
}
function changeStore (state, action) {
  switch (action.type) {
    case 'SET_NAME': {
      state.moveName = action.data
      break
    }
    case 'SET_IMAGE': {
      state.moveImage = action.data
      break
    }
  }
}

hoz.store.dispatch({
  type: 'SET_NAME',
  data: '厥後的我們'
})

這就是一個hoz運用,經由過程簡約的模板語法聲明式的將數據襯着進DOM體系。
且一切東西都是響應式的。

自創redux,flux等的頭腦,引入狀況治理

在狀況治理方面自創redux的頭腦,完成了單向數據流的治理。
重要定義了state,action,changeStore,dispatch4個觀點。

state

寄存數據

var state = {
  moveName: '',
  moveImage: ''
}

changeStore

相當於redux中的reducer,寄存着對數據的一切操縱

function changeStore (state, action) {
  switch (action.type) {
    case 'SET_NAME': {
      state.moveName = action.data
      break
    }
    case 'SET_IMAGE': {
      state.moveImage = action.data
      break
    }
  }
}

吸收action,實行對應的要領,修正state中的數據。不同於redux的是,redux放回的是全新的state,而它是直接操縱當前的state,因為state中的數據已經由過程Object.defineProperty要領舉行了跟蹤,這個背面再將。

action和dispatch

當想要對數據舉行修正的時刻,我們必需經由過程提交action的體式格局,在changeStore中去修正state

hoz.store.dispatch({
  type: 'SET_NAME',
  data: '厥後的我們'
})

這個就是hoz的狀況治理戰略

 view -> dispatch -> action -> changeStore -> state -> view

優點

跟着運用的日趨龐雜,數據量的增大,假如不對數據舉行響應的治理,治理不停變化的狀況,是異常難題的。狀況在什麼時刻,因為什麼緣由,發作了怎樣的變化都難以視察。

  1. 這意味着運用中一切的數據都遵照雷同的生命周期,如許可以讓運用變得越發可展望且輕易明白。
  2. 我們可以從 changeStore 中看到state可以發作的一切變化
  3. 對state修正的唯一體式格局就是向changeStore提交action,所以數據的每一次變化都邑從一個處所流過,輕易我們的debug等操縱。

引入virtual dom 和diff算法

總所周知,因為dom元素的巨大,以及dom操縱輕易引發頁面重排的緣由,直接操縱dom機能是異常異常差的。
所以hoz引入了virtual dom算法,用原生的JavaScript對象去映照dom對象,因為原生JavaScript對象的操縱更快更簡樸。
怎樣映照呢?比方

class VNode {
  constructor (sel, tagName, id, className, el, children, data, text, key) {
    this.tagName = tagName // DIV
    this.sel = sel // div#id.class
    this.id = id // id
    this.className = className // []
    this.children = children // []
    this.el = el // node
    this.data = data // {}
    this.key = key
    this.text = text
  }
}

export default VNode

只是一個JavaScript對象,代表一個dom元素。

我依據hoz組織函數中傳進來的 id 所指向的元素作為根元素豎立一個假造dom樹,當數據轉變的時刻,不直接操縱dom,而是在假造dom樹上舉行操縱修正。然後經由過程diff算法對照新舊假造dom樹,對實在dom舉行最小單元的修正。

數據響應式道理

hoz式怎樣做到數據的響應式的呢?這裏重要經由過程藉助Object.defineProperty要領完成了一個宣布/定閱形式,經由過程Object.defineProperty修正state中數據的getter和setter屬性,在初次襯着的時刻,在getter中將對應的定閱者添加到一個主題對象中去,當數據轉變的時刻在setter中挪用對應數據的主題對象的notify要領宣布音訊,關照每一個定閱者更新。

state ->   data ->   publisher      一對多的關聯
                        |
                       Dep
                        |
view -> {{data}} -> subscribers

願望人人藉此為基本一同去完美它。項目地點:Hoz.js,迎接人人start,fork,以及提issues。

    原文作者:holyZhengs
    原文地址: https://segmentfault.com/a/1190000015011839
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞