一、ref函数
一般用来把简单数据类型处理响应式数据
声明的变量值用ref包裹,修改时通过 name.value去修改
let name = ref('张三')
二、reactive函数
用来把对象类型的数据处理成响应式数据(数组也可以处理)
我们把reactive包裹的对称为源对象,返回的为代理对象(Proxy的实例对象,简称proxy对象)
不管数据有多深,多复杂,reactive都可以进行处理,定义的响应式数据是深层次的
内部主要通过基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作,实现数据劫持
let job = reactive({
type:'前端开发',
salary:'30K'
})
- 他们之间的区别
从数据角度
ref用来定义基本数据类型,而reactive用来定语对象(数组)类型
ref可可以定义对象(数组类型),但是内部还是借助reactive去实现响应式效果
原理上
ref通过Object.defineProperty中的get和set去实现时响应式(数据劫持)
而reactive是通过ES6中的Proxy实现数据劫持,并通过Reflect去操作源对象内部的数据
使用角度上
ref去操作数据需要用到 . value,读取不需要
reactive的操作和读取不需要 . value
三、vue3响应式原理
在vue2中我们主要通过Object.defineProperty中的get和set来实现 数据代理 和 数据劫持
而在vue3中主要是通过Proxy代理对象,
去拦截对象中任意属性的变化,包括属性的读写、属性的添加、和属性的删除等等,
通过relect反射对象,去对被代理对象进行操作
Proxy
Proxy接收两个参数,并返回一个代理对象
第一个参数是要代理的源对象,第二个参数是一个配置对象
在配置对象中有get、set、deleteProperty等配置项
读取属性的时候触发get
修改或者追加属性的时候触发set
删除属性的时候触发deleteProperty
- get和deleteProperty接收两个参数
target:源对象
propName:发生变化的属性名
- set接收三个参数
target:源对象
propName:发生变化的属性名
value:新值
Reflect 反射对象
- Reflect.get( obj , ' a ')读取 接收两个参数
1.要读取的对象
2.要读取的属性
- Reflect.set( obj , ' a ' , 111 ) 修改 接受三个参数
1.要修改的对象
2.要修改的属性
3.修改的值
- Reflect.deleteProerty( obj , ' a ') 删除 接收两个参数
1.要删除的对象
2.要删除的属性
如果删除成功返回值为true,反之为false
let person = {
a: 'a',
b: {
c: 'c'
}
}
//模拟vue3中实现响应式
const p = new Proxy(person, {
get (target, propName) {
console.log(`有人读取了p身上的${propName}属性`);
return Reflect.get(target,proName)
},
set (target, propName, value) {
console.log(`有人修改了p身上的${propName}属性,我要去更新页面了`);
Reflect.set(target,proName,value)
},
deleteProperty (target, propName) {
console.log(`有人删除了p身上的${propName}属性,我要去更新页面了`);
return Reflect.deleteProperty(target,proName)
},
})