废话不多说,直接上代码,代码有备注!!!
- 方式一:利用 defineProperty 方法
<div><input type="text" placeholder="请输入数据" /></div>
<!--渲染区域-->
<div class="item-box"></div>
<button>重置</button>
<script>
let btn = document.querySelector("button");
let inpEl = document.querySelector("input[type='text']");
let itemBox = document.querySelector(".item-box");
// 数据
let data = {};
// 监听对象的属性(数据)变化
Object.defineProperty(data, "message", {
get() {
// 更新视图层渲染
itemBox.style["background"] = "skyblue";
// 将文本框内容设置为空 (重置)
inpEl.value = "";
return this.value;
},
set(v1) {
// 更新视图层渲染
itemBox.innerHTML = v1;
// 数据层赋值
this.value = v1;
},
});
// 利用 input 标签的事件
inpEl.oninput = () => (data.message = inpEl.value);
btn.onclick = () => (data.message = "");
</script>
- 方式2: 利用 Proxy 和 Reflect 方法
tool.js
// 渲染函数
let render = (renderData) => {
let ul = document.querySelector("ul");
let str = "";
renderData.forEach((e) => {
str += `<li>${e.id} - ${e.name}</li>`;
});
ul.innerHTML = str;
};
// 数据绑定
let binding = (target, bindEl) => {
return new Proxy(target, {
get(target, prop) {
return Reflect.get(target, prop);
},
set(target, prop, value) {
// 判断设置的属性是否为绑定的属性
if (Reflect.has(target, bindEl)) {
// 渲染页面
render(value);
}
// 更新数据
Reflect.set(target, prop, value);
},
});
}
<!--渲染区域-->
<ul></ul>
<button>模拟向后台请求数据</button>
<!-- 导入插件包 -->
<script src="./tool.js"></script>
<script>
let btn = document.querySelectorAll("button");
// 数据集合
let data = {
list: [],
b: 0,
};
// 将 data 中的 list 进行双向绑定
data = binding(data, "list");
// 初始化数据(为了方便演示)
data.list = [
{ id: 1, name: "产品1" },
{ id: 2, name: "产品2" },
{ id: 3, name: "产品3" },
{ id: 4, name: "产品4" },
];
// 发送请求
btn[0].onclick = () => {
// 向后端请求回来的数据
let res = [
{ id: 5, name: "产品5" },
{ id: 6, name: "产品6" },
{ id: 7, name: "产品7" },
{ id: 8, name: "产品8" },
];
// 将后端数据放到数据集合中的 list
data.list = data.list.concat(res);
};
</script>