Vue 的双向绑定
Vue 的双向绑定是面试超级高频的题,因为双向绑定的设计非常精妙,这次我们尝试用原生来实现一下双向绑定吧。
双向绑定指的是:
(1)用户输入的内容能够修改 Vue 实例上的数据;
(2)Vue 可以监测到该修改,并且更新视图;
双向绑定的简易版实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input type="text" id="input" />
<div><span>用户将我修改为:</span><span id="text"></span></div>
</body>
<script>
// 页面视图初始化
const input = document.querySelector("#input");
const text = document.querySelector("#text");
let obj = { data: 1 };
text.innerHTML = obj.data;
// 经过代理之后通过 p 来对代理对象的属性进行获取和设置时会触发 getter 和 setter
const p = new Proxy(obj, {
// 当 input 事件触发时,obj.data 被赋值,会触发setter
// 此时就监听到了数据的变化,需要做的事刷新视图
set: (target, property, newVal, proxyObj) => {
console.log("setter触发了");
text.innerHTML = newVal;
},
});
// 事件绑定:用户输入的数据同步到代理对象,这样才能触发 setter
// 注意:input 是实时触发的,而 change 事件是当 value 发生修改且输入框失焦时触发
input.addEventListener("input", (e) => {
// 注意是设置代理对象,才会触发 setter
p.data = e.target.value;
});
</script>
</html>
总结一波
原生实现双向绑定可以通过 input 事件和 proxy 代理来实现。
(1)实时收集数据
:借助输入框的 input 事件;
(2)JS 实现数据劫持
:借助 ES6 新特性:将收集到的数据赋值给代理对象 p,触发 proxy 实例的 setter 方法,这样就实现了 JS 对数据变化的监听;
(3)刷新视图
:在 setter 方法里面执行更新视图的函数,上面因为只是一个 Demo ,所以直接使用 innerHTML 来更新,实际情况中要结合发布订阅模式来实现数据驱动 UI 更新。