data.age=25 // 触发set方法
vue3.0双向数据绑定Proxy
Vue3.0中的响应式采用了ES6中的Proxy方法。
Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)
语法:
const p = new Proxy(target, handler)
参数target
表示要使用Proxy
包装的对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)
参数handler
是一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理p
的行为
let obj = { a: 1, b: 2 } const proxy = new Proxy(obj, { get: function(target, prop, receiver) { return prop in target ? target[prop] : 0 }, set: function(target, prop, value, receiver) { target[prop] = 666 } }) console.log(proxy.a) // 1 console.log(proxy.c) // 0 proxy.a = 10 console.log(proxy.a) // 666 obj.b = 10 console.log(proxy.b) // 不是666 而是10
以上代码中obj
是我们要代理的目标对象,get
,set
方法是参数handler
的两个属性,具体如下:
handler.get()
接收三个参数,第一个参数target
为代理的目标对象,第二个参数prop
是代理的目标对象的属性,第三个参数是Proxy
或者继承Proxy
的对象,通常是proxy
本身。
handler.set()
接收四个参数,其中三个参数都与get
方法相同,唯独多出来一个value
表示新的属性值。
上述代码表示当访问proxy
的属性时,进行拦截判断,该属性是否是目标对象的属性,如果是那么就将其值返回出来,否则就返回0
。
当对proxy
上的属性进行重写时,将重写的该属性赋值为666
。
注意: 此时对数据的劫持,只是劫持了代理对象proxy
,而跟原对象obj
没有任何关系,对obj
进行操作,也不会监听到。
用proxy
实现一个简易版的数据响应:
let app = document.getElementById(‘app’) let input = document.getElementById(‘input’) let obj = { // 源数据 text:‘hello world’ } let proxy = new Proxy(obj, { set: function(target, prop, value){ // input事件触发进行劫持,触发update方法 target[prop] = value update(value) } }) function update(value){ // update方法用于同步dom更新 app.innerHTML = value input.value = value }