利用 ES6 的字符串模板和 JQuery 簡單理解 MVVM

jopen 9年前發布 | 13K 次閱讀 ES6 jQuery Ajax框架

把自己對這MVVM設計模式的理解整理并記錄,僅作自己以后查詢之用。

先說前端為什么需要 MVVM 或者 FLUX。在我看來,是為了保證不那么優秀的前端er在團隊中寫出不那么垃圾的代碼,即使確實十分垃圾,也不會污染到團隊中其他同事的代碼,其它的設計模式應該也具有這種作用。

通過代碼對比理解MVVM

MVVM 是 Model-View-ViewModel (雙向數據綁定)的簡寫。不管是 MVVM 或者是 FLUX, 都強調的是視圖和數據的分離。MVVM 是將視圖和數據分離之后,通過 ViewModel 將數據和視圖進行綁定。

View 一般是指模板,例如 Handlerbars ,或者 ES6 的字符串模板,寫法如下:

let message = 'hello,world!!'
let demo = `
<div id="demo">
    <p>${message}</p>
</div>
`

然后通過 jQuery 插入 body 中

$('body').html(demo)

對于 demo 便是View,message 是此 View 指定的 Model。由于在這個例子中并沒有交互,僅僅只是為了說明視圖和模型, 所以并沒有 VM 部分。

下面的例子是一個完整的用 JQuery 實現的 MVVM 模式寫法

//------ Model
let model = {
  value: 1,
  fns: [],
  set: function(v) {
    this.value = v
    this.fns.forEach(fn => fn.call(this, this.value))
  },
  on: function(fn) {
    this.fns.push(fn)
  }
};


//------ View
let demo = `
<div>
<p>${model.value}</p>
<input value='${model.value}' />
<button id="button1">+1</button>
</div>
`

$('body').html(demo)

//------ ViewModel

$('input').on('keyup', function() {
    model.set($(this).val()|0)
})


$('button#button1').on('click', function() {
    model.set(model.value + 1)
})


model.on(function(value) {
  $('p').html(value)
  $('input').val(value)
})

在這個例子中, input輸入的內容會實時顯示在p標簽中,而button被點擊之后,也會對p標簽的值和input標簽的值都做+1處理;如果我們按照通常的 jQuery 來處理的話應該怎么做?

$('input').on('keyup', function() {
  let value = $(this).val()|0;
  $('p').html(value)
  $('input').val(value)
})

$('button').on('click', function() {
    let value = $('input').val()|0 + 1;
    $('p').html(value)
    $('input').val(value)
})

從這兩段代碼來看,并沒有太大區別,甚至下面一段代碼看起來更短。然而下面一段代碼將 視圖和模型的處理寫到了一起,試想一下,當我們想再增加一個 -1 的button 呢?對于 MVVM的模式,只要再寫

<button id='button2'>-1</button>
$('button#button2').on('click', function() {
    model.set(model.value - 1)
})

即可。

而對于傳統的方式,還需要先取得當前input值或p的值,然后再進行-1操作,最后還需要將input和p的innerHTML都修改一次。隨著DOM的增加,處理難度的差距越來越大,越來越不容易理解,修改一次,如履薄冰。

通過這個小例子可以看出 MVVM 相對傳統的寫法的最大的優勢:

  1. 視圖和模型的分離,視圖可以獨立模型進行開發;只需約定模型的結構即可。

  2. 雙向數據綁定,視圖和模型可以通過VM互相改變。

  3. 基于約定俗成的模式,可以將爛代碼控制在最小范圍內,也很難寫出爛代碼。

ps: 按照我的理解 Angular 中對于基礎的VM進行了封裝,所以在模板中綁定數據之后,數據更新,會自動更新視圖。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!