1. 程式人生 > >簡要理解vue的mvvm模式中的雙向資料繫結

簡要理解vue的mvvm模式中的雙向資料繫結

mvvm(Model-View-ViewModel)模式:
由檢視(View)、檢視模型(ViewModel)、模型(Model)三部分組成,結構如下圖。
這裡寫圖片描述
通過這三部分實現UI邏輯、呈現邏輯和狀態控制、資料與業務邏輯的分離。

使用MVVM模式有幾大好處:

  1. 低耦合。View可以獨立於Model變化和修改,一個ViewModel可以繫結到不同的View上,當View變化的時候Model可以不變,當Model變化的時候View也可以不變。

  2. 可重用性。可以把一些檢視的邏輯放在ViewModel裡面,讓很多View重用這段檢視邏輯。

  3. 獨立開發。開發人員可以專注與業務邏輯和資料的開發(ViewModel)。設計人員可以專注於介面(View)的設計。

  4. 可測試性。可以針對ViewModel來對介面(View)進行測試

vue中支援mvvm的核心就是雙向資料繫結機制。
vue資料雙向繫結是通過資料劫持結合釋出者-訂閱者模式的方式來實現的,那麼vue是如果進行資料劫持的,我們可以先來看一下通過控制檯輸出一個定義在vue初始化資料上的物件是個什麼東西。

var vm = new Vue({
    data: {
        obj: {
            a: 1
        }
    },
    created: function () {
        console.log(this.obj);
    }
});

這裡寫圖片描述
我們可以看到屬性a有兩個相對應的get和set方法,為什麼會多出這兩個方法呢?因為vue是通過Object.defineProperty()來實現資料劫持的。

雙向資料繫結的模式是view改變是更新data,data改變的時候更新view。view改變後更新data可以通過事件監聽來實現,這不是問題,問題是data改變後如何更新到view。
這裡寫圖片描述
參考vue的做法就是通過set,get來實現。

下面我們來看兩個data改變後更新view的DOM:
1.改變prop這個屬性的值後,通過set立即更新到view

<!DOCTYPE html> 
<html>
<head> <meta charset="UTF-8"> <title>test</title> </head> <body> <div id="test">測試</div> <script> var view = document.getElementById("test"); var data = {}; var i=0; Object.defineProperty(data, "prop", { set: function(newValue) { //當data.b的值改變的時候更新#test的檢視 view.textContent=newValue; }, get: function() { } }); setInterval(function(){ console.log(data) i++; data.prop = "data.prop的值更新了,我要更新檢視"+i; },1000); </script> </body> </html>
var Book = {}
var name = '';
Object.defineProperty(Book, 'name', {
  set: function (value) {
    name = value;
    console.log('你取了一個書名叫做' + value);
  },
  get: function () {
    return '《' + name + '》'
  }
})
Book.name = 'vue權威指南';  // 你取了一個書名叫做vue權威指南
console.log(Book.name);  // 《vue權威指南》

我們通過Object.defineProperty( )設定了物件Book的name屬性,對其get和set進行重寫操作,顧名思義,get就是在讀取name屬性這個值觸發的函式,set就是在設定name屬性這個值觸發的函式,所以當執行 Book.name = ‘vue權威指南’ 這個語句時,控制檯會打印出 “你取了一個書名叫做vue權威指南”,緊接著,當讀取這個屬性時,就會輸出 “《vue權威指南》”,因為我們在get函式裡面對該值做了加工了。如果這個時候我們執行下下面的語句,控制檯會輸出什麼?
這裡寫圖片描述

以上是對vue中的mvvm和雙向資料繫結的簡要理解,內容不深,適合入門,不喜勿噴!喜歡可以點個贊或者關注,嘻嘻!