网站后台演示地址,网站建设与维护方案,分公司可以建设网站,做网站 怎么推广#x1f308;个人主页#xff1a;前端青山 #x1f525;系列专栏#xff1a;Vue篇 #x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue3-响应式函数 目录
ref 响应式函数
引言#xff1a;
ref 函数
reactive 函数
Reactive 与…
个人主页前端青山 系列专栏Vue篇 人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue3-响应式函数 目录
ref 响应式函数
引言
ref 函数
reactive 函数
Reactive 与 ref 对比
vue3响应式原理
1、vue3响应式原理
ref 响应式函数
引言
如下代码当点击执行changeFn函数修改setup中定义的变量时发现页面中的name和age的数据并没有修改说明该数据不是响应式数据
templatediv111/divp{{ name }}--{{ age }}/pbutton clickchangeFnchangeFn/button
/template
script
export default {name: App,setup() {//定义变量let name 张三;let age 20;// 定义方法function changeFn() {name 李四;age 30;}return {//setup函数返回值为一个对象name,age,changeFn,};},
};
/script
ref 函数 它是 vue3中的一个函数一般用于将基本类型数据处理成响应式数据。 作用定义一个基本类型的响应式的数据只有数据成为响应式数据这样当数据变化时才能被监测到。 使用时需要从vue中引入 语法const xxx ref(数据变量)结果 返回一个 RefImpl 的引用对象获取时为 xxx.value 在页面模板中使用数据直接 使用插值表达式不需要加value p姓名:{{ name }}/p因为vue3会自动帮你.value,所以可以拿到值 ref 函数实现数据响应式的原理还是利用了vue2的Object.defineProperty() 给数据设置 get set 监听函数如下图 接收的数据类型可以是基本类型(实现响应式原理为Object.defineProperty()也可以是对象类型(当为对象时实现响应式的原理就是Proxy不是Object.defineProperty())
点击如下change事件修改name 和age
templatediv!--name这个ref 引用对象在使用时不需要加value,vue3会自动帮你加value,所以可以拿到值--p{{ name }}--{{ age }}/pp{{ job.type }}--{{job.salary}}/pp clickchange说话/p/div
/template
script
import { ref } from vue; // 引入响应式函数ref
export default {name: App,setup() {let name ref(张三); //返回一个 ref 引用对象let age ref(20);console.log(name)// 当ref传的参数为对象时let job ref({type: 前端工程师,salary: 20k,});function change() {name.value 李四; // ref对象.value 修改其值age.value 30;job.value.type 后端开发工程师;job.value.salary 30k;}return {name,age,change,job};},
};
/script
reactive 函数
1.定义一个对象类型的响应式数据返回一个Proxy 实例对象,不能用于基本数据类型否则报错。基本类型响应式数据使用ref)。
语法const 代理对象 reactive(源对象) 接收一个对象或数组返回一个代理对象即Proxy源对象 使用时先从vue中引入
script
import { reactive } from vue;
...
/script 代码如下
templatep{{ job.type }} --{{ job.salary }}--{{ job.like.a.b }}--{{job.content}}/pp v-for(item, index) in foodArr :keyindex{{ item }}/pbutton clickchangeFnchangeFn/button
/template
script
import { reactive } from vue;
export default {name: App,components: {},setup() {//定义对象let job reactive({type: 前端工程师,salary: 20k,like:{a:{b:不告诉你}}});console.log(job);//定义数组let foodArr reactive([刷抖音, 敲代码]);console.log(foodArr);// 定义方法function changeFn() {job.type 后端开发工程师;job.salary 30k;job.content 写代码; // 给对象添加属性foodArr[0]买包包 // 通过下标修改数组}return {//setup函数返回值为一个对象job,changeFn,foodArr};},
};
/script vue3中使用proxy 实现的数据响应去掉了vue2中不能检测到对象添加属性和通过下标修改数组而无法检测的情况。
Reactive 与 ref 对比
1、数据定义角度对比 ref用来定义基本数据类型 reactive 用来定义 对象或数组类型数据 注意ref也可以定义对象或数组类型数据它内部还是通过reactive转换成代理对象
2、原理角度对比 ref通过Object.defineProperty() 的get和set 实现数据的响应式 即数据劫持 reactive 通过Proxy 实现数据响应式的并通过Reflect 来操作源对象数据的。
3、从使用角度对比 ref 定义的数据操作时需要使用 .value, 而插值表达式中使用时不需要使用 .value reactive 定义的数据操作都不需要 .value
vue3响应式原理 对象数据新增属性和删除属性不存在vue2.x 中的问题了。
templatedivp{{ person.name }}/pp{{ person.age }}/pp{{ person.sex }}/pbutton clickaddSex添加属性/buttonbutton clickdeleteSex删除属性/button/div
/template
script
import { reactive } from vue;
export default {name: App,components: {},setup() {let person reactive({name: 张三,age: 20,});console.log(person);//定义添加属性function addSex() {person.sex 男;console.log(person);}// 定义删除属性function deleteSex() {delete person.sex;console.log(person);}return {person,addSex,deleteSex,};},
};
/script 数组数据直接通过修改下标修改数组不存在vue2.x 中的问题了。
templatedivp v-for(item, index) in person.like :keyindex{{ item }}/pbutton clickchange修改数组的值/button/div
/template
script
import { reactive } from vue;
export default {name: App,components: {},setup() {let person reactive({ name: 张三,age: 20,like: [打球, 敲代码],});console.log(person); // proxy 实例对象function change() {person.like[0] 打台球;}return {person,change,};},
};
/script
1、vue3响应式原理
首先说一下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 就是 dataconsole.log(读取p上个${propName}属性);return Reflect.get(target, propName)},// 修改和设置属性set(target, propName, value) {// value 为赋的值console.log(修改p的${propName}属性);// target[propName] valueReflect.set(target, propName, value)
},//删除属性deleteProperty(target, propName) {console.log(删除p上的${propName}属性);// return delete target[propName]return Reflect.deleteProperty(target, propName)}})