vue 資料雙向繫結實現

2021-09-14 02:15:41 字數 4500 閱讀 9042

之前每件事都差不多,直到現在才發現差很多。

現在才發現理清一件事的原委是多麼快樂的一件事,我們共同勉勵。

紙上得來終覺淺,絕知此事要躬行

懶得扯淡,直接正題

ps: 文章略長。

model->view編譯器

其基於 訂閱者-發布者模式,簡單的講就是訂閱者訂閱資料,一旦訂閱的資料變更過後,更新繫結的view檢視。

這裡有明確的分工,分別是***、發布器和訂閱器,這3者相互協作,各司其職。

過2s資料更改,更新到檢視

顧名思義,***,***,監聽的就是資料的變化

建立

發布器;發布器 新增

訂閱器;

發布器 通知

訂閱器

需要解決訂閱者的新增和發布器通知訂閱器的時機

object.difineproperty為我們提供了方便,其語法如下:

var obj = {};

object.defineproperty(obj, 'a', );

console.log(obj.a); // 輸出a

definepropery除了可以定義數值以外,還可以定義 get 和 set 訪問器,如下:

var obj = {};

var value = 'a';

object.defineproperty(obj, 'a', ,

set: function (val)

});console.log(obj.a);

obj.a = 'b';

console.log(obj.a);

執行結果如下所示:

資料的變化無非就是讀和寫,由此,我們可以得出訂閱器的新增和發布器通知訂閱器的時機,就是屬性值的獲取和重置。

function observe(data) 

object.keys(data).foreach((val, key) => )

}function definereactive(data, key, val) ,值為$`);

return val;

},set: function (newvalue) ,變為$`);

val = newvalue;

}});

}var obj =

}observe(obj);

新增

訂閱器;通知

訂閱器

function dep () 

dep.prototype.addsub = function(sub);

dep.prototype.notify = function());

};

發布器**寫好了,我們再重新修改一下*****。主要修改點為:新增訂閱器和發布器通知訂閱器

function definereactive(data, key, val) ,值為$`);

+ dep.addsub();

return val;

},set: function (newvalue) ,變為$`);

val = newvalue;

}

更新檢視
function watcher (vm, key, cb) 

watcher.prototype.update = function()

};watcher.prototype.get = function();

訂閱器**寫好了,我們再重新修改一下*****。主要修改點為:如何新增訂閱器

enumerable: true,

configurable: true,

get: function ()

return val;

},set: function (newvalue) );

}

var vm = new vue(, document.getelementbyid('root'), 'name');

settimeout(() => , 2000);

還有一點,通常資料的變更是直接使用vm.name,而非vm.data.name,其實也很簡單,直接使用**,vm.name讀取和寫都**到vm.data.name上即可。

+    var self = this;

+ object.keys(this.data).foreach(function(property, index) );

+ var watcher = new watcher(this, key, function (name) );

-}+}

++vue.prototype.proxyproperty = function(property),

+ set: function (value)

+ });

+};

詳細**參考github專案

$ git clone 

$ cd vue-like

$ git checkout model2view

上面的例項看起來,有點問題,我們是寫死監聽的資料,然後修改dom上的innerhtml,實際中,肯定不會這樣,需要在dom中繫結資料,然後動態監聽資料變化。

首先需要明確編譯器有哪些工作需要做

檢視繫結資料,2s後資料更新,更新到檢視

對dom結構的解析這裡使用文件片段,其dom操作效能優於其他。

function compile (options, vm) 

compile.prototype.createelement = function (ele)

return fragment;

}compile.prototype.compileelement = function (el) \}/;

var text = node.textcontent;

if (reg.test(text))

if (node.childnodes && node.childnodes.length > 0)

});}compile.prototype.compiletext = function (node, key) );

}compile.prototype.updatetext = function (node, text)

compile.prototype.viewrefresh = function();

詳細**參考github專案

$ git clone 

$ cd vue-like

$ git checkout compile

這個比較簡單,在compile 解析時,判斷是否是元素節點,如果元素節點中包含指令v-model,從中讀取監聽的資料屬性,再從 model中讀取,除此以外還要繫結乙個input事件,用於view -> model

詳細**參考github專案

詳細**參考github專案

$ git clone 

$ cd vue-like

$ git checkout event

比如說建立、初始化、更新、銷毀等。

詳細**參考github專案

$ git clone 

$ cd vue-like

$ git checkout lifecircle

vue實現雙向資料繫結

object.defineproperty 方法會直接在乙個物件上定義乙個新屬性,或者修改乙個物件的現有屬性,並返回這個物件。object.defineproperty 方法有三個引數 引數 功能 作用 obj 要修改或定義key值的物件 key 對應obj物件的裡面某有已有或要修改的屬性 opti...

Vue如何實現資料雙向繫結

說明 index.html lang en head p p v text msg p v text car.color p v html msg p v html car.color p type text v model msg v on click clickfn 點我button div...

vue實現資料雙向繫結原理

vue實現資料雙向繫結主要是採用資料劫持結合發布者 訂閱者的模式的方式來實現。通過object.defineproperty 的get和set來劫持每個屬性,在資料發生變化時通過發布者發訊息給訂閱者,觸發相應的監聽回掉。具體就是先把說有的資料做乙個資料劫持。第一先修改資料,在input框輸入值的時候...