什么是雙向數(shù)據(jù)綁定?
Vue是個(gè)MVVM框架软免,當(dāng)數(shù)據(jù)發(fā)生變化時(shí)膏萧,視圖也跟著發(fā)生變化,當(dāng)視圖發(fā)生變化時(shí)蝌蹂,數(shù)據(jù)也會(huì)跟著同步變化孤个。雙向數(shù)據(jù)綁定沛简,一般是對(duì)于UI控件來說的硅急,非UI控件不會(huì)涉及到雙向數(shù)據(jù)綁定。
Vue雙向數(shù)據(jù)綁定是怎么實(shí)現(xiàn)的佳遂?
官方文檔上說得很簡單——用v-model指令在表單元素上創(chuàng)建雙向數(shù)據(jù)綁定。
那么丑罪,v-model背后的實(shí)現(xiàn)原理又是什么呢?
它的基本原理是利用Object.defineProperty()這個(gè)方法重新定義了對(duì)象獲取屬性值(get)和設(shè)置屬性值(set)的操作來實(shí)現(xiàn)的凤壁。
使用Object.defineProperty()實(shí)現(xiàn)一個(gè)簡單的雙向數(shù)據(jù)綁定小例子:
<!doctype html>
<html>
<head>
<title></title>
</head>
<body>
<input id="text" type="text" />
<p id="p"></p>
</body>
<script type="text/javascript">
var obj = {};
Object.defineProperty(obj,"name",{
get:function(){
return name;
},
set:function(value){
document.getElementById("text").value = value;
document.getElementById("p").innerHTML = value;
}
});
var input = document.getElementById("text");
input.addEventListener("input",function(event){
var text = event.target.value;
obj.name = text;
});
</script>
</html>
效果:
可以看到,我們?cè)谳斎肟蜉斎雰?nèi)容時(shí)拧抖,<p>標(biāo)簽內(nèi)會(huì)顯示對(duì)應(yīng)的內(nèi)容煤搜,這說明實(shí)現(xiàn)了model=>view的綁定唧席。
現(xiàn)在我們?cè)诳刂婆_(tái)給obj.name賦值擦盾,發(fā)現(xiàn)賦值后輸入框的內(nèi)容變成了所賦的那個(gè)值:
說明實(shí)現(xiàn)了view=>model的綁定。
當(dāng)然vue的實(shí)現(xiàn)比這復(fù)雜得多淌哟,詳細(xì)請(qǐng)查看網(wǎng)上大牛們的博客迹卢。
這種實(shí)現(xiàn)雙向數(shù)據(jù)綁定的方法叫作數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式。
簡單解釋什么是數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式:
1徒仓、數(shù)據(jù)劫持:在本例中,通過Object.defineProperty來劫持name屬性的setter掉弛,getter症见,在數(shù)據(jù)變化時(shí)通知訂閱者谋作,觸發(fā)相應(yīng)的回調(diào)瓷们;
2谬晕、發(fā)布者/訂閱者:訂閱者可定義為希望接收到通知的對(duì)象;發(fā)布者可定義為激活事件的對(duì)象攒钳。在本例中不撑,文本輸入框相當(dāng)于一個(gè)訂閱者文兢,Obj相當(dāng)于一個(gè)發(fā)布者。文本框通過addEventListener接收Obj給它的啟動(dòng)通知焕檬,觸發(fā)相應(yīng)的函數(shù)姆坚,進(jìn)行視圖更新。
一般來說实愚,實(shí)際應(yīng)用中會(huì)涉及多個(gè)訂閱者兼呵,這時(shí)就需要一個(gè)消息訂閱器來管理這些訂閱者;另外還需要指令來初始化訂閱者腊敲。
詳情及更復(fù)雜的例子可參考這篇博文:
http://www.cnblogs.com/libin-1/p/6893712.html