如果使用object.defineproperty,實現乙個最簡單的雙向繫結其實很簡單,只需如下:
上面這個demo就是vue雙向繫結最簡化的原理。
二、替換元素
想想我們使用vue時的規則
new vue(寫上頁面結構:});
<我們把vue抽象為乙個建構函式,傳入這些值div
id >
<
input
type
='text'
v-model
='text'
>
}div
>
function替換掉節點中所有的}:vue(options);
function這樣就可以成功替換掉}:compile (node, vm)\}/;//
匹配}內任意字元
//節點型別為元素
if (node.nodetype === 1) };}
//節點型別為text
if(node.nodetype === 3) }};
function
getallnode(node, vm)
};
三、繫結元素
上面我們只是替換了元素,但還沒有實現繫結
實現資料繫結,就要用到definedproperty的set和get方法:
首先我們要給vue的所有屬性都新增set和get方法:
function再來明確我們要做的事,獲取輸入的值,改變vue中相應的data的值,同時改變}中的值;vue()
//遍歷
function
observe (obj, vm)}//
新增set和get
function
active (obj, key, val) ,
set(newval);
val =newval;
}});
}
我們已經給data的每個屬性都新增了get和set的方法,現在要做的就是如何觸發它們。
觸發它肯定是在賦值的時候,所以我們在有v-model屬性的節點監聽輸入事件,同時賦值,觸發set事件:
function我們監聽了input事件,接下來要獲取輸入的值並同步改變文字;compile (node, vm))
node.value = vm.data[name];// 替換輸入框的值為data中的值
node.removeattribute('v-model');}};
}//************
}
我們肯定希望只希望**改變了就對**做處理就行了,所以我們引入乙個簡單的發布——訂閱元件:
function在新增set和get的同時訂閱事件:pubsub()
pubsub.prototype =,
pub:
function
()) }
}
function新增乙個方法,來在pubsub發出通知時處理事件,我們命名為watcher:active (obj, key, val)
return
val;
},set(newval);
val =newval;
//發出通知
pubsub.pub();
}});
}
function這個watcher我們在什麼時候新增呢?當然是在一開始的時候(compile裡):watcher(vm, node, name)
watcher.prototype =,
//獲取data中的屬性值
get()
}function
getallnode(node, vm)
};
function至此,便模擬了整個資料繫結的流程compile (node, vm)\}/;//
匹配}內任意字元
//節點型別為元素
if (node.nodetype === 1) )
node.value = vm.data[name];//
替換輸入框的值為data中的值
node.removeattribute('v-model');}};
};//節點型別為text
if(node.nodetype === 3) }};
最後理清整個過程的思路
建立vue:
input事件:
模擬Vue雙向資料繫結
function eventemit this.callbacks eventemit.prototype.on function eventname,fn this.callbacks eventname push fn eventemit.prototype.emit function even...
原生JS模擬Vue雙向資料繫結
童鞋們都應該知道vue2.x很重要的特性 資料雙向繫結 虛擬dom 所以在面試的時候就經常有面試官問小白同學說資料雙向繫結原理是什麼,虛擬dom是什麼,給我實現乙個唄。所以給大家展示乙個最簡的雙向繫結的案例,也參考了網上一些資料。至於虛擬dom的實現後面再說吧,網上資料也很多很全因為畢竟react都...
vue中的資料雙向繫結
學習的過程是漫長的,只有堅持不懈才能到達到自己的目標。1.vue中資料的雙向繫結採用的時候,資料劫持的模式。其實主要是用了es5中的object.defineproperty 來劫持每個屬性的getter,和setter。這也正是vue不相容ie8以下的原因。2.object.defineproer...