<template>
<div>
<h2>{{person.name}}</h2>
<h2 v-show='person.age'>{{person.age}}</h2>
<h2>{{person.sex}}</h2>
<h2>{{person.address}}</h2>
<button @click='changeName'>修改姓名</button>
<button @click='changeAge'>修改年龄</button>
<button @click='addAdress'>添加地址</button>
<button @click='deleteAge'>删除年龄</button>
<hr>
<ul>
<li v-for="(item, index) in hobby" :key="index">
{{ item }}
</li>
</ul>
<button @click='addHobby'>添加hobby</button>
<button @click='updateHobby'>修改hobby</button>
</div>
</template>
<script>
import { reactive} from'vue'
export default {
setup() {
const person = reactive({
name:'张三',
age:20,
sex:'女'
})
function changeName(){
person.name += '!'
}
function changeAge(){
person.age ++
}
function addAdress(){
person.address = '陕西省'
}
function deleteAge(){
delete person.age
}
const hobby = reactive(['画画','游泳'])
function addHobby(){
hobby.push('唱歌')
}
function updateHobby(){
hobby[0] = '烫头'
}
return { person, changeName,changeAge, addAdress, deleteAge, hobby, addHobby, updateHobby }
},
}
</script>
原理:
<script>
const person = {
name: '张三',
age: 20
}
const p = new Proxy(person, {
get(target, propName) {
console.log('有人读取了属性')
console.log(target, propName)
return target, propName
},
//新增属性或者修改属性时调用
set(target, propName, value) {
console.log('有人修改了值')
target[propName] = value
},
deleteProperty(target, propName){
console.log('有人删除了属性')
return delete target[propName]
}
})
</script>
//真正的vue3实现响应式
<script>
const person = {
name: '张三',
age: 20
}
const p = new Proxy(person, {
get(target, propName) {
console.log('有人读取了属性')
console.log(target, propName)
// return target, propName
return Reflect.get(target, propName)
},
//新增属性或者修改属性时调用
set(target, propName, value) {
console.log('有人修改了值')
// target[propName] = value
Reflect.set(target, propName, value)
},
deleteProperty(target, propName){
console.log('有人删除了属性')
// return delete target[propName]
return Reflect.defineProperty(target, propName)
}
})
</script>
总结:
- 实现原理
- 通过 Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
- 通过Reflect(反射): 对源对象的属性进行操作。
- MDN文档中描述的Proxy与Reflect:
关于代理与反射,可以看这篇博文
模拟Vue3中实现响应式