目录
Vue2.x的响应式
1、实现原理:
- 对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)
- 数组类型:通过重写更新数组的一系列方法来实现拦截。
Object.defineProperty(data,'count',{
get( ){ },
set( ){ }
})
2、存在问题:
- 新增属性、删除属性,界面不会更新
- 直接通过下标修改数组,界面不会自动更新
<template>
<div id="app">
<h1>我是Vue2的效果</h1>
<h2 v-show="person.name">姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<h2 v-show="person.sex">性别:{{person.sex}}</h2>
<button @click="addSex">添加一个sex属性</button>
<button @click="deleteName">删除name属性</button>
</div>
</template>
<script>
import Vue from 'vue'
export default {
name: 'App',
data(){
return{
person:{
name:'张三',
age:18
}
}
},
methods:{
addSex(){
//this.person.sex='女'
Vue.set(this.person,'sex','女')
},
deleteName(){
//delete this.person.name
Vue.delete(this.person,'name','女')
}
}
}
</script>
Vue2的响应式
let person ={
name:'张三',
age:18
}
//模拟Vue2中的实现响应式
let p = {}
Object.defineProperty(p,'name',{
configurable:true, //可删除的
get(){
return person.name
},
set(value){
console.log('有人修改了name属性,我发现了,我要去更新界面!')
person.name = value
}
})
Object.defineProperty(p,'age',{
configurable:true,
get(){
return person.age
},
set(value){
console.log('有人修改了age属性,我发现了,我要去更新界面!')
person.age = value
}
})
Vue3.0的响应式原理
实现原理:
- 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等。
- 通过Reflect(反射):对被代理对象的属性进行操作。
window.proxy 代理对象
let person ={
name:'张三',
age:18
}
//模拟Vue3中的实现响应式
const p = new Proxy(person,{})
let person ={
name:'张三',
age:18
}
//模拟Vue3中的实现响应式
const p = new Proxy(person,{
//有人读取p的某个属性时调用
get(target,propName){
console.log(`有人读取了p身上的${propName}属性`)
return target[propName]
},
//有人修改或追加p的某个属性时调用
set(target,propName,value){
console.log(`有人修改了p身上的${propName}属性,我要去更新界面了`)
target[propName] = value
},
//有人删除p的某个属性时调用
deleteProperty(target,propName){
console.log(`有人删除了p身上的${propName}属性,我要去更新界面了`)
return delete target[propName]
}
})
window.Reflect 反射对象
let person ={
name:'张三',
age:18
}
//模拟Vue3中的实现响应式
const p = new Proxy(person,{
//有人读取p的某个属性时调用
get(target,propName){
console.log(`有人读取了p身上的${propName}属性`)
return Reflect.get(target,propName)
},
//有人修改或追加p的某个属性时调用
set(target,propName,value){
console.log(`有人修改了p身上的${propName}属性,我要去更新界面了`)
Reflect.set(target,propName,value)
},
//有人删除p的某个属性时调用
deleteProperty(target,propName){
console.log(`有人删除了p身上的${propName}属性,我要去更新界面了`)
return Reflect.deleteProperty(target,propName)
}
})