Proxy
响应式原理Vue2
的响应式Object.defineProperty()
对属性的读取、修改进行拦截(数据劫持)Object.defineProperty(data, 'count', {
get(){},
set(){}
})
解决方式:
this.$set()\Vue.set()
,this.$delete()\Vue.delete()
解决方式:
this.$set()\Vue.set()
,Array.splice(0,1,‘demo’)
Vue3
的响应式(Proxy
)Proxy(代理)
:拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等Reflect(反射)
:对被代理的对象的属性进行操作MDN
文档中描述的Proxy
和Reflect
:
Proxy
<script>
let data = {
name: '张三',
age: 19
}
// 模拟Vue3响应式
const p = new Proxy(data, {
// 接收参数 target:传入对象, propName: 读取到的具体属性名
// 有人读取了某个属性
get(target, propName){
console.log(`有人读取了p身上的${propName}属性`,target, propName)
return target[propName]
},
// 有人修改了p的某个属性、或新增某个属性
set(target, propName, value){
console.log(`有人修改或新增了p身上的${propName}属性`)
target[propName] = value
},
// 有人删除某个属性
deleteProperty(target, propName){
console.log(`有人删除了p身上的${propName}属性`)
return delete target[propName]
}
})
</script>
效果图:
Reflect
:
Reflect.get(target, propertyKey[, receiver])
获取对象身上某个属性的值,类似于target[name]
。Reflect.set(target, propertyKey, value[, receiver])
将值分配给属性的函数。返回一个Boolean
,如果更新成功,则返回true。Reflect.deleteProperty(target, propertyKey)
作为函数的delete
操作符,相当于执行delete target[name]
。Reflect.defineProperty(target, propertyKey, attributes)
和Object.defineProperty()
类似。如果设置成功就会返回 true
举个例子:
<script>
let data = {
name: '小明'
}
// Object.defineProperty操作, 重复定义会报错,不能继续往下执行,检验错误写在try...catch中
// Object.defineProperty(data, 'age',{
// get(){
// return 19
// }
// })
// Object.defineProperty(data, 'age',{
// get(){
// return 20
// }
// })
// Reflect操作,直接返回Boolean,不会打断运行
let x1 = Reflect.defineProperty(data, 'age',{
get(){
return 19
}
})
console.log(x1)
let x2 = Reflect.defineProperty(data, 'age',{
get(){
return 20
}
})
console.log(x2)
if(x1){
console.log('设置成功')
} else{
console.log('设置失败')
}
console.log('@@@')
</script>
3.所以模拟Proxy
响应:
// 模拟Vue3响应式
const p = new Proxy(data, {
// 接收参数 target:传入对象, propName: 读取到的具体属性名
// 有人读取了某个属性
get(target, propName){
console.log(`有人读取了p身上的${propName}属性`,target, propName)
// return target[propName]
return Reflect.get(target, propName)
},
// 有人修改了p的某个属性、或新增某个属性
set(target, propName, value){
console.log(`有人修改或新增了p身上的${propName}属性`)
// target[propName] = value
return Reflect.set(target, propName, value)
},
// 有人删除某个属性
deleteProperty(target, propName){
console.log(`有人删除了p身上的${propName}属性`)
// return delete target[propName]
return Reflect.deleteProperty(target, propName)
}
})