vue2响应式原理概述
- vue2的响应式原理主要通过
Object.defineProperty()
,实现对属性的读取、修改进行拦截。 Object.defineProperty()
有可传入三个参数- 对象
- 对象的属性名
- 属性描述符
- 其中属性描述符又可作划分
- 数据描述符:
value
:属性的值,默认为undefined
writable
:是否可以修改属性的值,默认为false
- 存取描述符
get
:当属性被访问时调用set
:当属性被修改时调用
- 其他描述符
configurable
:是否可以删除当前属性,默认为false
enumerable
:属性是否可枚举,不可枚举则某些情况该属性不会被遍历出来,默认为false
- 数据描述符:
- 其中属性描述符又可作划分
vue2响应式简写
let mvp_coder = {
name:'jack',
age:99
}
let sim_coder = {}
// 模拟vue2实现响应式
Object.defineProperty(sim_coder,'name',{
configurable:true,
get(){
return mvp_coder.name
},
set(value){
console.log('监听到有人修改name,需要去更新页面');
mvp_coder.name = value
}
})
Object.defineProperty(sim_coder,'age',{
get(){
return mvp_coder.age
},
set(value){
console.log('监听到有人修改age,需要去更新页面');
mvp_coder.age = value
}
})
vue2存在的问题
- 新增属性、删除属性, 界面不会更新。
可以使用
this.$set(array, index, data)
解决
Vue3响应式原理概述
-
- 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
const dif_coder = new Proxy(mvp_coder,{
get(target, propName){
console.log(`读取了dif_coder身上的${propName}`,target[propName]);
return target[propName]
},
set(target, propName, value){
console.log(`修改了dif_coder身上的${propName}`);
target[propName] = value
},
defineProperty(target, propName){
console.log(`删除了dif_coder身上的${propName}`);
return delete target[propName]
}
})
-
- 通过Reflect(反射): 对源对象的属性进行操作。
- Reflect是什么? es6的新方法,会返回boolean值
vue3响应式简写
const dif_coder = new Proxy(mvp_coder,{
get(target, propName){
console.log(`读取了dif_coder身上的${propName}`,target[propName]);
return Reflect.get(target, propName)
},
set(target, propName, value){
console.log(`修改了dif_coder身上的${propName}`);
return Reflect.set(target, propName, value)
},
defineProperty(target, propName){
console.log(`删除了dif_coder身上的${propName}`);
return Reflect.deleteProperty(target, propName)
}
})