Vue 2.x
vue通过Object.defineProperty 劫持传进来的数据, 然后在数据getter的时候订阅重新编译模板的消息,然后通过js监听元素的事件,这里input事件也好,keyup事件也好,总是监听输入框值变化,将新的值重新赋值给被劫持的data,这样就会触发setter函数,再setter函数中就会去发布重新编译模板的消息;
手写一个数据绑定 :
<input id="input" type="text" />
<div id="text"></div>
let input = document.getElementById("input");
let text = document.getElementById("text");
let data = { value: "" };
Object.defineProperty(data, "value", {
set: function(val) {
text.innerHTML = val;
input.value = val;
},
get: function() {
return input.value;
}
});
input.onkeyup = function(e) {
data.value = e.target.value;
};
Vue 3.x
通过proxy也是实现对传进来的数据的劫持,然后在数据getter的时候订阅重新编译模板的消息,然后通过js监听元素的事件,这里input事件也好,keyup事件也好,总是监听输入框值变化,将新的值重新赋值给被劫持的data,这样就会触发setter函数,再setter函数中就会去发布重新编译模板的消息;
<body>
hello,world
<input type="text" id="model">
<p id="word"></p>
</body>
<script>
const model = document.getElementById("model")
const word = document.getElementById("word")
var obj= {};
const newObj = new Proxy(obj, {
get: function(target, key, receiver) {
console.log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function(target, key, value, receiver) {
console.log('setting',target, key, value, receiver);
if (key === "text") {
model.value = value;
word.innerHTML = value;
}
return Reflect.set(target, key, value, receiver);
}
});
model.addEventListener("keyup",function(e){
newObj.text = e.target.value
})
</script>