千鋒長沙前端培訓:Vue的雙向資料繫結原理

千鋒雲端計算發表於2021-11-22

       vue.js 是採用資料劫持結合釋出者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在資料變動時釋出訊息給訂閱者,觸發相應的監聽回撥。下面千鋒 給大家說說 具體實現步驟,感興趣的可以看看:

src=http___

       當把一個普通 Javascript 物件傳給 Vue 例項來作為它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 都加上 setter和getter 這樣的話,給這個物件的某個值賦值,就會觸發setter,那麼就能監聽到了資料變化。

       compile解析模板指令,將模板中的變數替換成資料,然後初始化渲染頁面檢視,並將每個指令對應的節點繫結更新函式,新增監聽資料的訂閱者,一旦資料有變動,收到通知,更新檢視。

       Watcher訂閱者是Observer和Compile之間通訊的橋樑,主要做的事情是:

       1、在自身例項化時往屬性訂閱器(dep)裡面新增自己。

       2、自身必須有一個update()方法。

       3、待屬性變動dep.notice()通知時,能呼叫自身的update()方法,並觸發Compile中繫結的回撥,則功成身退。

       MVVM作為資料繫結的入口,整合Observer、Compile和Watcher三者,通過Observer來監聽自己的model資料變化,通過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通訊橋樑,達到資料變化 -> 檢視更新;檢視互動變化(input) -> 資料model變更的雙向繫結效果

       //vue實現資料雙向繫結的原理就是用Object.defineproperty()重新定義(set方法)物件設定屬性值和(get方法)獲取屬性值的操縱來實現的。

       //Object.property()方法的解釋:Object.property(引數1,引數2,引數3) 返回值為該物件obj

       //其中引數1為該物件(obj),引數2為要定義或修改的物件的屬性名,引數3為屬性描述符,屬性描述符是一個物件,主要有兩種形式:資料描述符和存取描述符。這兩種物件只能選擇一種使用,不能混合使用。而get和set屬於存取描述符物件的屬性。

       //這個方法會直接在一個物件上定義一個新屬性或者修改物件上的現有屬性,並返回該物件。

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

</head>

<body>

<div id="myapp">

<input v-model="message" /><br>

<span v-bind="message"></span>

</div>

<script type="text/javascript">

var model = {

message: ""

};

var models = myapp.querySelectorAll("[v-model=message]");

for (var i = 0; i < models.length; i++) {

models[i].{

model[this.getAttribute("v-model")] = this.value;

}

}

// 觀察者模式 / 鉤子函式

// defineProperty 來定義一個物件的某個屬性

Object.defineProperty(model, "message", {

set: function(newValue) {

var binds = myapp.querySelectorAll("[v-bind=message]");

for (var i = 0; i < binds.length; i++) {

binds[i].innerHTML = newValue;

};

var models = myapp.querySelectorAll("[v-model=message]");

for (var i = 0; i < models.length; i++) {

models[i].value = newValue;

};

this.value = newValue;

},

get: function() {

return this.value;

}

})

</script>

</body>

</html>


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69916964/viewspace-2843514/,如需轉載,請註明出處,否則將追究法律責任。

相關文章