目录回顾 Vue2.x 的响应式vue3的响应式回顾 vue2.x 的响应式 实现原理: 对象类型:通过object.defineProperty()对属性的读取、修改进行拦截(数据
实现原理:
object.defineProperty()
对属性的读取、修改进行拦截(数据劫持)Object.defineProperty(data,'count ",{
get(){},
set(){}
})
存在问题:
但是 vue2 给了解决方法,我们看以下代码:
<template>
<div>
<h2>我是vue2写的效果</h2>
<h4 v-show="person.name">姓名:{{person.name}}</h4>
<h4>年龄:{{person.age}}</h4>
<h4 v-show="person.sex">性别:{{person.sex}}</h4>
<h4>爱好:{{person.hobby}}</h4>
<button @click="addSex">添加sex属性</button>
<button @click="deleteName">删除name属性</button>
<button @click="changeHobby">修改爱好</button>
</div>
</template>
<script>
import Vue from 'vue'
export default {
name: 'App',
data(){
return{
person:{
name:'张三',
age:18,
hobby:['学习','吃饭']
}
}
},
methods:{
addSex(){
//这样直接加是不行的
//this.person.sex = '男'
this.$set(this.person,"sex",'男')
//Vue.set(this.person,"sex",'男')
},
deleteName(){
//这样直接加是不行的
//delete this.person.name
//this.$delete(this.person,'name')
Vue.delete(this.person,"name")
},
changeHobby(){
//这样直接加是不行的
//this.person.hobby[0] = '逛街'
//可以这样
this.$set(this.person.hobby,0,'逛街')
//或
//this.person.hobby.splice(0,1,"逛街")
},
}
}
</script>
我们可以用 js 模拟 vue2 的响应式:
<script>
//源数据
let person = {
name:"张三",
age:18
}
let p = {}
//模拟vue2实现响应式
Object.defineProperty(p,"name",{
configurable:true,
get() {//有人读取name时调用
return person.name
},
set(v) {
person.name = v
console.log("有人修改了name属性,我发现了,我要去更新界面");
}
})
Object.defineProperty(p,"age",{
get() {//有人读取age时调用
return person.age
},
set(v) {
person.age = v
console.log("有人修改了age属性,我发现了,我要去更新界面");
}
})
</script>
先输出 person,然后看下 p,当修改 name 或 age 时会检测到
它的问题是,如果增加一个 sex 属性,vue 不会检测到,虽然增加了 sex 属性,但它不像 name 和 age 有 getter 和 setter,不是响应式的
同样,当删除 name 属性时也监测不到
<template>
<h1>一个人的信息</h1>
<h3 v-show="person.name">姓名:{{ person.name }}</h3>
<h3>年龄:{{ person.age }}</h3>
<h3 v-show="person.sex">性别:{{ person.sex }}</h3>
......
<button @click="changeInfo">修改人的信息</button>
<button @click="addSex">添加一个sex属性</button>
<button @click="deleteName">删除一个name属性</button>
</template>
<script>
import {Reactive} from 'vue'
export default {
name: 'App',
setup() {
......
function changeInfo() {
......
person.hobby[0] = '学习'
}
function addSex() {
person.sex = "男"
}
function deleteName() {
delete person.name
}
return {
......
addSex,
deleteName
}
}
}
</script>
模拟 vue3 中的响应式:
<script>
//源数据
let person = {
name:"张三",
age:18
}
const p = new Proxy(person,{
//有人读取p的某个属性时调用
get(target, p, receiver) {
console.log(`有人读取了p身上的${p}属性`);
//return target[p]
return Reflect.get(target,p)
},
//有人修改、增加p的某个属性时调用
set(target, p, value, receiver) {
console.log(`有人修改了p身上的${p},我要去更新界面了`);
//target[p] = value
Reflect.set(target,p,value)
},
//有人删除p的某个属性时调用
deleteProperty(target, p) {
console.log(`有人删除了p身上的${p},我要去更新界面了`);
//return delete target[p]
return Reflect.deleteProperty(target,p)
}
})
</script>
实现原理:
MDN文档中描述的 Proxy 与 Reflect
Reflect 是一个内置的对象,它提供拦截 javascript 操作的方法。Reflect不是一个函数对象,因此它是不可构造的。
new Proxy(data,{
//拦截读取属性值
get (target, prop){
return Reflect.get(target,prop)
},
//拦截设置属性值或添加新属性
set (target,prop, value) {
return Reflect.set(target,prop, value)
},
//拦截删除属性
deleteProperty (target,prop) {
return Reflect.deleteProperty(target,prop)
}
})
proxy.name = "tom"
到此这篇关于一文详解Vue3响应式原理的文章就介绍到这了,更多相关Vue3响应式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: 一文详解Vue3响应式原理
本文链接: https://www.lsjlt.com/news/151584.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0