vue2响应式实现原理:
对象类型:通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持)。
数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行包裹)。
Object.defineProperty(data,'conunt',{
get(){},
set(){}
})
弊端在 :1、该get和set方法只能监控查询和修改,对新增和删除监控无效,
2、直接通过下标修改数组,也监控不了
只能通过2中方法解决
1:通过this.$set(this.person,'sex','女')
2:通过Vue.$set(this.person,'sex','女')
1:通过this.$delete(this.person,'sex','女')
2:通过Vue.$delete(this.person,'sex','女')
数组:
1:this.$set(this.person.hobby,0,‘逛街’)
2:this.person.hobby.splice(0,1,'逛街)
直接通过html文件实现vue2和vue3进行对比:
vue2:
先在vscode插件中下载open in browser方便直接打开html

<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
// 元数据
let person = {
name: '张三',
age: 18
}
// 模拟vue2中实现响应式
let p = {}
Object.defineProperty(
p, 'name', {//有人读取name时调用
get() {
return person.name
},
set(value) {
console.log('有人修改了name属性,我发现了,我要去更新新界面')
person.name = value
}
}
)
Object.defineProperty(
p, 'age', {//有人读取age时调用
get() {
return person.age
},
set(value) {
console.log('有人修改了age属性,我发现了,我要去更新新界面')
person.age = value
}
}
)
</script>
</body>
</html>


可以看到新增和删除无效
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
// 元数据
let person = {
name: '张三',
age: 18
}
// 模拟vue2中实现响应式
// let p = {}
//#region
// Object.defineProperty(
// p, 'name', {//有人读取name时调用
// configurable : true,
// get() {
// return person.name
// },
// set(value) {
// console.log('有人修改了name属性,我发现了,我要去更新新界面')
// person.name = value
// }
// }
// )
// Object.defineProperty(
// p, 'age', {//有人读取age时调用
// configurable : true,
// get() {
// return person.age
// },
// set(value) {
// console.log('有人修改了age属性,我发现了,我要去更新新界面')
// person.age = value
// }
// }
// )
//#endregion
// Vue3中的实现响应式
const p = new Proxy(person,{
get(target,propName){
console.log(`有人读取了p身上的${propName}某个属性`,target,propName)
return target[propName]
},
set(target,propName,value){
console.log(`有人修改了p身上的${propName}某个属性,我要去更新界面了`,target,propName,value)
target[propName] = value
},
deleteProperty(target,propName){
console.log(`有人删除了p身上的${propName}某个属性,我要去更新界面了`,target,propName)
return delete target[propName]
}
})
</script>
</body>
</html>

可以看到增删改查都能监控!
es6新特性使用反射Reflect:
与直接操作区别,能返回数值表示是否成功,适用于框架封装
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
// 元数据
let person = {
name: '张三',
age: 18
}
// 模拟vue2中实现响应式
// let p = {}
//#region
// Object.defineProperty(
// p, 'name', {//有人读取name时调用
// configurable : true,
// get() {
// return person.name
// },
// set(value) {
// console.log('有人修改了name属性,我发现了,我要去更新新界面')
// person.name = value
// }
// }
// )
// Object.defineProperty(
// p, 'age', {//有人读取age时调用
// configurable : true,
// get() {
// return person.age
// },
// set(value) {
// console.log('有人修改了age属性,我发现了,我要去更新新界面')
// person.age = value
// }
// }
// )
//#endregion
// Vue3中的实现响应式
const p = new Proxy(person,{
get(target,propName){
console.log(`有人读取了p身上的${propName}某个属性`,target,propName)
// return target[propName]
return Reflect.get(target,propName)
},
set(target,propName,value){
console.log(`有人修改了p身上的${propName}某个属性,我要去更新界面了`,target,propName,value)
// target[propName] = value
Reflect.set(target,propName,value)
},
deleteProperty(target,propName){
console.log(`有人删除了p身上的${propName}某个属性,我要去更新界面了`,target,propName)
// return delete target[propName]
return Reflect.deleteProperty(target,propName)
}
})
</script>
</body>
</html>