Vue實作資料雙向綁定原理:
采用資料劫持結合釋出者-訂閱者模式的方式,通過 Object.defineProperty() 來劫持各個屬性的setter,getter,在資料變動時釋出消息給訂閱者,觸發相應監聽回調。當把一個普通 Javascript 對象傳給 Vue 執行個體來作為它的 data 選項時,Vue 将周遊它的屬性,用 Object.defineProperty() 将它們轉為 getter/setter。
這裡來簡單模拟一下雙向綁定。
特點
1.比如input被監視,當輸入發送改變時,會将資料推送到模型中。
2.當模型中的資料發生改變時,會映射到視圖上。
思路
1.用defineProperty 劫持對象,添加好getter/setter方法,對劫持對象進行指派時會執行setter,取值時執行getter。
2.頁面監視很容易想到事件監聽,輸入框用addEventListener 添加 input事件,輸入發生改變時,觸發事件回調,将值指派給劫持的對象,觸發劫持對象的setter,在setter中把新資料寫到模型中、同時更新到頁面上。
代碼:
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
輸入:<input type='text' id='inputText'/><br>
動态值:<span id="show"></span>
</body>
<script>
var inputText = document.getElementById("inputText");
var show = document.getElementById("show");
//輸入框添加 input事件
inputText.addEventListener("input",function(e){
//給劫持對象設定為輸入後的值
defineObj.value = e.target.value;
})
//劫持對象
var defineObj = {};
//defineProperty進行劫持
Object.defineProperty(defineObj, 'value', {
configurable: true,
enumerable: true,
get:function() {
return val;
},
set: function(newVal){
val = newVal;
//設定輸入值跟随變化
inputText.value = val;
//設定顯示值跟随變化
show.innerHTML = val;
}
})
</script>
</html>
最終效果
在文本輸入框輸入值,會同步展示出來,記憶體中也同樣發生了改變;
改變記憶體中的資料值,直接映射到頁面上。