个人主页:前端青山
系列专栏:Vue篇
人终将被年少不可得之物困其一生
依旧青山,本期给大家带来vue篇专栏内容:vue3-响应式函数
目录
ref 响应式函数
引言:
ref 函数
reactive 函数
Reactive 与 ref 对比
vue3响应式原理
1、vue3响应式原理
如下代码:当点击执行changeFn函数,修改setup中定义的变量时,发现页面中的name和age的数据并没有修改,说明该数据不是响应式数据
111
{{ name }}--{{ age }}
它是 vue3中的一个函数,一般用于将基本类型数据处理成响应式数据。
作用:定义一个基本类型的响应式的数据,只有数据成为响应式数据,这样当数据变化时,才能被监测到。
使用时需要从vue中引入
语法:const xxx =ref(数据变量);结果 返回一个 RefImpl 的引用对象,获取时为 xxx.value
在页面模板中使用数据直接 使用插值表达式,不需要加value
姓名:{{ name }}
,因为vue3会自动帮你.value,所以可以拿到值ref 函数实现数据响应式的原理还是利用了vue2的Object.defineProperty() 给数据设置 get set 监听函数,如下图:
接收的数据类型可以是基本类型(实现响应式原理为Object.defineProperty()),也可以是对象类型(当为对象时,实现响应式的原理就是Proxy不是Object.defineProperty())
点击如下change事件,修改name 和age
{{ name }}--{{ age }}
{{ job.type }}--{{job.salary}}
说话
1.定义一个对象类型的响应式数据,返回一个Proxy 实例对象,不能用于基本数据类型,否则报错。(基本类型响应式数据使用ref)。
语法:const 代理对象= reactive(源对象) ,接收一个对象或数组,返回一个代理对象(即Proxy源对象)
使用时先从vue中引入
代码如下:
{{ job.type }} --{{ job.salary }}--{{ job.like.a.b }}--{{job.content}}
{{ item }}
vue3中使用proxy 实现的数据响应去掉了vue2中不能检测到对象添加属性和通过下标修改数组而无法检测的情况。
1、数据定义角度对比:
ref用来定义:基本数据类型
reactive 用来定义: 对象或数组类型数据
注意:ref也可以定义对象或数组类型数据,它内部还是通过reactive转换成代理对象
2、原理角度对比:
ref通过Object.defineProperty() 的get和set 实现数据的响应式 即(数据劫持)
reactive 通过Proxy 实现数据响应式的,并通过Reflect 来操作源对象数据的。
3、从使用角度对比:
ref 定义的数据操作时需要使用 .value, 而插值表达式中使用时,不需要使用 .value
reactive 定义的数据操作都不需要 .value
对象数据新增属性和删除属性,不存在vue2.x 中的问题了。
{{ person.name }}
{{ person.age }}
{{ person.sex }}
数组数据直接通过修改下标,修改数组,不存在vue2.x 中的问题了。
{{ item }}
首先说一下Reflect的作用。
// Reflect是window下的一个内置对象
// 1. 使用reflect 访问数据
let obj = {
name: '张三',
age: 20
}
console.log(Reflect.get(obj, 'name')); // 张三
// 2.使用Reflect 修改数据
Reflect.set(obj, 'age', 50)
console.log(obj);
//3.使用Reflect删除数据
Reflect.deleteProperty(obj, 'name')
console.log(obj);
vue3响应原理代码:
通过Proxy代理,拦截对象中任意属性的变化,包括属性的读取,修改、设置、删除。
通过Reflect 反射对被代理对象的属性进行操作。
let data = {
name: "张三",
age: 30
}
console.log(Proxy);
// 使用p 对象代理data, Proxy为window 下的内置代理函数
let p = new Proxy(data, {
// 读取属性
get(target, propName) {
// target 就是 data
console.log(`读取p上个${propName}属性`);
return Reflect.get(target, propName)
},
// 修改和设置属性
set(target, propName, value) {
// value 为赋的值
console.log(`修改p的${propName}属性`);
// target[propName] = value
Reflect.set(target, propName, value)
},
//删除属性
deleteProperty(target, propName) {
console.log(`删除p上的${propName}属性`);
// return delete target[propName]
return Reflect.deleteProperty(target, propName)
}
})