Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)
1.基本使用
let obj = {};
let handler = {
get(target, property) {
console.log(`${property} 被读取`);
return property in target ? target[property] : 3;
},
set(target, property, value) {
console.log(`${property} 被设置为 ${value}`);
target[property] = value;
}
}
let p = new Proxy(obj, handler);
p.name = 'tom' //name 被设置为 tom
console.log(p.age); //age 被读取 3
2.作为验证使用(常用)
let validator = {
set: function(obj,prop,value){
if(prop === 'age') {
if(!Number.isInteger(value)){
throw new Error("年龄不是整数")
}
if(value > 300){
throw new Error("年龄太大了")
}
}
obj[prop] = value
}
}
let person = new Proxy({},validator);
person.age = 100;
console.log(person.age) //100
person.age = 10.1 //报错 年龄不是整数
person.age = 500 //报错 年龄太大了
3.实现双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>proxy-VUE</title>
</head>
<style>
#app {
margin: 100px auto 0 auto;
width: 300px;
}
#btn {
margin: 10px auto;
}
</style>
<body>
<div id="app">
<input type="text" id="input" />
<div>您输入的是: <span id="title"></span></div>
<button type="button" name="button" id="btn">添加到todolist</button>
<ul id="list"></ul>
</div>
</body>
<script type="text/javascript">
// 数据绑定
const obj = {};
const arr = [];
const input = document.getElementById("input");
const title = document.getElementById("title");
const list = document.getElementById("list");
const btn = document.getElementById("btn");
// 渲染todolist列表
const Render = {
// 初始化
init: function(arr) {
const fragment = document.createDocumentFragment();
for (let i = 0; i < arr.length; i++) {
const li = document.createElement("li");
li.textContent = arr[i];
fragment.appendChild(li);
}
list.appendChild(fragment);
},
addList: function(val) {
const li = document.createElement("li");
li.textContent = val;
list.appendChild(li);
}
};
// 监听对象
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(target, key, value, receiver);
if (key === "text") {
input.value = value;
title.innerHTML = value;
}
return Reflect.set(target, key, value, receiver);
}
});
// 监听数组
const newArr = new Proxy(arr, {
get: function(target, key, receiver) {
return Reflect.get(target, key, receiver);
},
set: function(target, key, value, receiver) {
console.log(target, key, value, receiver);
if (key !== "length") {
Render.addList(value);
}
return Reflect.set(target, key, value, receiver);
}
});
// 初始化
window.onload = function() {
Render.init(arr);
};
input.addEventListener("keyup", function(e) {
newObj.text = e.target.value;
});
btn.addEventListener("click", function() {
newArr.push(parseInt(newObj.text));
});
</script>
</html>