Proxy对象英语创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找,赋值、枚举、函数调用等)
语法
const proxy = new Proxy(target, handler);
参数
target
要使用Proxy包装的目标对象,可以是任何类型的对象,包括原生数组,函数,甚至是另一个代理。
handler
一个对象,其属性是当执行一个操作时定义代理的行为的函数(可以理解为某种触发器)。
基本使用
const obj = {name: "Tony", age: 20}const proxy = new Proxy(obj, {get(obj, property) {// property: 对象的key// obj: 代理的对象return obj[property]},set(obj, property, value) {obj[property] = value;return true}})console.log(proxy.name)proxy.name = 'Tom'console.log(obj)
基本方法
handler.get()
描述:
-
语法:
new Proxy(obj, {get(obj, key, receiver) {return obj[key]}})
参数:
target:目标对象。
- key:被获取的属性名。
-
返回值:
-
handler.set()
描述:
set方法是设置属性值操作的捕获器。用于拦截设置属性值的操作
语法:
new Proxy(obj, {set(obj, key, value, receiver) {obj[key] = value;return true;}})
参数:
target:目标对象。
- key:属性名。
- value: 新属性值。
-
返回值:
set()方法应当返回一个布尔值。
-
语法:
function sum(a, b) {return a + b}const proxy = new Proxy(sum, {apply(target, thisArg, paramsList) {return target(paramsList[0] + paramsList[1] * 10);}})sum(1, 2) // 3proxy(1, 2) // 21
参数:
target:目标函数
- thisArg:被调用时的上下文对象。
-
返回值:
-
VueJs input 双向绑定实例
<!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" v-model="title"><input type="text" v-model="title"><div v-bind="title"></div><script>function View() {let proxy = new Proxy({},{get() {},set(obj, key, value) {document.querySelectorAll(`[v-model="${key}"]`).forEach(item => item.value = value)document.querySelectorAll(`[v-bind="${key}"]`).forEach(item => item.innerHTML = value)return true;}})this.init = function() {let inputs = document.querySelectorAll("[v-model]");inputs.forEach(item => {item.addEventListener('keyup', function() {proxy[this.getAttribute('v-model')] = this.value;})})}}new View().init()</script></body></html>
表单验证实例
<!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><style>.error {border: 5px solid red;}</style></head><body><input type="text" validate rule='max:5,min:2'><input type="text" validate rule='max:5,isNumber:true'><script>class Validate {max(value, len) {return value.length <= len;};min(value, len) {return value.length >= len;};isNumber(value) {return value instanceof Number}}function proxyFactory(value) {return new Proxy(value, {get(obj, key) {return obj[key]},set(obj, key, el) {const rule = el.getAttribute("rule");const validate = new Validate();let state = rule.split(',').every(rule => {const info = rule.split(":");return validate[info[0]](el.value, info[1]);});console.log(state);el.classList[state ? "remove" : "add"]('error');return true}})}const proxy = proxyFactory(document.querySelectorAll('[validate]'));proxy.forEach(item => {item.addEventListener('keyup', function() {proxy.set = this;})})</script></body></html>
