vue雙向數(shù)據(jù)綁定原理探究(附demo)
昨天被導(dǎo)師叫去研究了一下vue的雙向數(shù)據(jù)綁定原理。。。本來以為原理的東西都非常高深,沒想到vue的雙向綁定真的很好理解啊。。。自己動手寫了一個。
雙向綁定的思想
雙向數(shù)據(jù)綁定的思想就是數(shù)據(jù)層與UI層的同步,數(shù)據(jù)再兩者之間的任一者發(fā)生變化時都會同步更新到另一者。
雙向綁定的一些方法
目前,前端實(shí)現(xiàn)數(shù)據(jù)雙向數(shù)據(jù)綁定的方法大致有以下三種:
1.發(fā)布者-訂閱者模式(backbone.js)
思路:使用自定義的data屬性在HTML代碼中指明綁定。所有綁定起來的JavaScript對象以及DOM元素都將“訂閱”一個發(fā)布者對象。任何時候如果JavaScript對象或者一個HTML輸入字段被偵測到發(fā)生了變化,我們將代理事件到發(fā)布者-訂閱者模式,這會反過來將變化廣播并傳播到所有綁定的對象和元素。
2.贓值檢測(angular.js)
思路:通過輪詢的方式檢測數(shù)據(jù)變動。才特定的事件觸發(fā)時進(jìn)入贓值檢測。
大致如下:
• DOM事件,譬如用戶輸入文本,點(diǎn)擊按鈕等。( ng-click )
• XHR響應(yīng)事件 ( $http )
• 瀏覽器Location變更事件 ( $location )
• Timer事件( $timeout , $interval )
• 執(zhí)行 $digest() 或 $apply()
3.數(shù)據(jù)劫持(vue.js)
思路:使用Object.defineProperty對數(shù)據(jù)對象做屬性get和set的監(jiān)聽,當(dāng)有數(shù)據(jù)讀取和賦值操作時則調(diào)用節(jié)點(diǎn)的指令,這樣使用最通用的=等號賦值就可以觸發(fā)了。
wue雙向數(shù)據(jù)綁定小demo思路
① 構(gòu)造一個Wue對象,定義該對象的屬性el、data,創(chuàng)建對象的時候傳相應(yīng)數(shù)據(jù),并執(zhí)行init()方法。
var Wue=function(params){
this.el=document.querySelector(params.el);
this.data=params.data;
this.init();
};
② Init方法中執(zhí)行bindText和bindModel方法,這兩個方法分別是解析dom中綁定了w-model、w-text指令的html,并作相應(yīng)處理。
init:function(){
this.bindText();
this.bindModel();
}
③ bindText方法,把帶有w-text指令的元素放進(jìn)一個數(shù)組中,如:w-text='demo',然后令其innerHTML的值等于傳進(jìn)來的data[demo]。
bindText:function(){
var textDOMs=this.el.querySelectorAll('[w-text]'),
bindText;
for(var i=0;i<textDOMs.length;i++){
bindText=textDOMs[i].getAttribute('w-text');
textDOMs[i].innerHTML=this.data[bindText];
}
}
④ bindModel方法,把帶有w-model指令的元素(一般為form相關(guān)元素)放進(jìn)一個數(shù)組中,如:w-model='demo',為每一個元素綁定keyup事件(兼容瀏覽器寫法)。
bindModel:function(){
var modelDOMs=this.el.querySelectorAll('[w-model]'),
bindModel;
var _that=this;
for(var i=0;i<modelDOMs.length;i++){
bindModel=modelDOMs[i].getAttribute('w-model');
modelDOMs[i].value=this.data[bindModel]||'';
//數(shù)據(jù)劫持
this.defineObj(this.data,bindModel);
if(document.addEventListener){
modelDOMs[i].addEventListener('keyup',function(event) {
console.log('test');
e=event||window.event;
_that.data[bindModel]=e.target.value;
},false);
}else{
modelDOMs[i].attachEvent('onkeyup',function(event){
e=event||window.event;
_that.data[bindModel]=e.target.value;
},false);
}
}
}
⑤ 使用Object.defineProperty,定義set和get方法,并在set方法中調(diào)用bindText方法。這是利用了一旦w-model的值在input中被改變,會自動執(zhí)行set方法,所以只有在這個方法中調(diào)用更新w-text的方法即可。
defineObj:function(obj,prop,value){
var val=value||'';
var _that=this;
try{
Object.defineProperty(obj,prop,{
get:function(){
return val;
},
set:function(newVal){
val=newVal;
_that.bindText();
}
})
}catch (err){
console.log('Browser not support!')
}
}
⑥使用
html:<br><h3>雙向數(shù)據(jù)綁定demo</h3>
<div id="wrap">
<input type="text" w-model='demo'>
<h5 w-text='demo'></h5>
</div><br>js:
<script src='../js/wue.js'></script>
<script>
new Wue({
el:'#wrap',
data:{
demo:'winty'
}
})
</script>
完整demo下載:https://github.com/LuckyWinty/two-way-data
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關(guān)文章
解決el-tree節(jié)點(diǎn)過濾不顯示下級的問題
這篇文章主要介紹了解決el-tree節(jié)點(diǎn)過濾不顯示下級的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
Vue聲明式導(dǎo)航與編程式導(dǎo)航示例分析講解
這篇文章主要介紹了Vue中聲明式導(dǎo)航與編程式導(dǎo)航,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-11-11
Vue2?響應(yīng)式系統(tǒng)之深度響應(yīng)
這篇文章主要介紹了Vue2?響應(yīng)式系統(tǒng)之深度響應(yīng),文章基于Vue2?響應(yīng)式系統(tǒng)的相關(guān)資料展開對Vue2?深度響應(yīng)的介紹,需要的小伙伴可以參考一下2022-04-04
安裝vue無法運(yùn)行、此系統(tǒng)無法運(yùn)行腳本問題及解決
這篇文章主要介紹了安裝vue無法運(yùn)行、此系統(tǒng)無法運(yùn)行腳本問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03

