首先说一下我自己的理解,
以v-model为例,输入框里输入的值会同步到data中,而如果修改data的值,输入框的中的内容也会发生变化。
若将输入框作为视图层,data作为逻辑层
视图层到逻辑层: 可以用oninput事件来模拟,
逻辑层到视图层: 通过defineProperty来对setter进行修改,当监听到对象属性发生变化的时候,做出相应的操作(这里是修改input框的内容)
<!DOCTYPE html>
<head>
<title>模拟vue的双向绑定</title>
</head>
<body>
<input id="txt" name="txt" type="text" />
<script>
const input = document.getElementById('txt');
var data = {
value: undefined
};
input.addEventListener('input', function(e) {
data.value = e.target.value;
});
(function() {
let value;
Object.defineProperty(data, 'value', {
set: function(newValue) {
console.log('set');
input.value = newValue;
value = newValue;
console.log(value);
},
get: function() {
console.log('get');
return value;
}
});
})();
</script>
</body>
解释一下为什么使用var来声明data,因为let声明的是局部变量,而var在函数外声明的是全局变量,这里为了直接在控制台中修改data.value的值,便于window.data.value = xxx(省略window也可)来看对应输入框的变化。