前言

一个基本类型的数据,想要变成响应式数据,那么需要通过ref函数包裹,而如果是一个对象的话,那么需要使用reactive函数

reactive可将对象变成响应式

将一个对象类型的数据变为响应式,如果是基本数据类型,那用ref

const 代理对象 = reactive(被代理对象)接收一个对象(或数组),返回一个代理器对象(proxy的实例对象简称proxy对象)
const obj = reactive({name: 'itclanCoder',age: 10
})console.log(obj.name);
console.log(obj.age);

reactive定义的响应式数据是深层次的,内部基于Es6当中的proxy实现,通过代理对象操作源对象内部数据都是响应式的,reactive可以直接响应式数组

Vue2.x的响应式

实现原理

[1]. 对象类型: 通过Object.defineProperty()对属性的读取,修改进行拦截,数据劫持

[2]. 数组类型: 通过重写更新数组的一系列方法来实现拦截(对数组的变更方法进行包裹)

Object.definePropety(data,'count', {get(){},set(){}
})

存在的问题:

新增属性: 删除属性,界面不会更新

直接通过下标修改数组,界面不会自动更新

Vue3.0的响应式

实现原理

[1]. 通过proxy(代理)拦截对象中任意属性的变化,包括:属性值的读写,属性的添加,属性的删除等

[2]. 通过Refect(反射): 对被代理对象的属性进行操作

Vue2.0中,针对直接给对象添加属性,页面并不会更新,需要使用this.$set(原对象,属性名,属性值)或者Vue.set(原对象,属性名,属性值)

data(){return {person: {name: '张三',age: 18,hobby: ["吃饭",'学习']}},methods: {addSex() {// this.person.sex = '女'  // 这样直接添加属性,页面不会更新// 方法1-需要使用this.$set(),给一个属性追加一个属性this.$set(this.person,'sex','女')// 方法2:解决办法,此方式要引入import Vue from 'vue'Vue.set(this.person,'sex','女')},deleteName() {// console.log(this.person.name)// delete this.person.name   无法删除属性// console.log(this.person.name);// 给一个对象移除一个响应式数据使用this.$deletethis.$delete(this.person,'name');// 或者方法2,使用deleteVue.delete(this.person,'name');},updateHobby() {// this.person.hobby[0] = '逛街',无法通过下标方式修改数组项,页面不更新// 正确写法this.$set(this.person.hobby,0,'逛街');// 或者Vue.set(this.person.hobby,0,'逛街');// 调用数组的重写的方法this.person.hobby.splice(0,1,'逛街')}}
}

Vue3.0响应式

通过proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写,属性的添加,属性的删除等 通过Reflect(反射):对被代理(源)对象的属性进行操作

const proxy = 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'

Vue2.0

// 源数据
let person = {name: '张三',age: 18
}// 模拟Vue2中实现响应式
let p = {};
Object.defineProperty(p,'name',{get() {return person.name},set(value) { // 有人修改了name时调用console.log('有人修改了Name属性,我发现了,我要去更新界面');person.name = value}
}) Object.defineProperty(p,'age',{congigurable: true,  // 可配置属性,如果设置为true,那么可以使用delete删除属性get() {return person.age},set(value) { // 有人修改了name时调用console.log('有人修改了Name属性,我发现了,我要去更新界面');person.age = value}
})

那在Vue3的响应式是如何实现的

let person = {name:'张三',age:18
}// 模拟Vue3中实现的响应式
const p = new Proxy(person,{  // 第一个参数为原对象,p为代理对象// 有人读取p的某个属性时调用get(target,propName) {console.log('有人读取了p身上的${propName}个属性',target,propName); // b为读取的属性//return target[propName]return Reflect.get(target,propName)},// 有人修改p的某个属性,或给p追加某个属性时调用set(target,propName,value) {console.log(target,propName,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)}})  // 第一个参数是指定的对象

get,set,deleteProperty主要目的是能捕获到操作属性的响应式,而直接删除,添加是静态的,不是响应式的

proxy能捕获到操作属性的增删改查操作

Reflect.get(obj,'a')
Reflect.set(obj,'a','4')
Reflect.deleteProperty(obj,a)
Reflect.defineProperty(obj,'c',{})

Reflect有返回值

reactive对比ref

从定义数据角度对比

[1]. ref用来定义:基本类型数据 [2]. reactive用来定义: 对象(或数组)类型数据

备注:ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象

从原理角度对比

ref通过Object.defineProperty()的get与set来实现响应式(数据劫持) reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内容的数据

从使用角度对比

ref定义的数据:在js里面操作数据需要.value,读取数据时模板中直接读取不需要.value reactive定义的数据:操作数据与读取数据:均不需要.value

reactive不用直接用于普通的变量,但是一般来说可以放置在代理对象里面去做代理

总结

ref用于基本数据类型的响应式数据处理,而reactive则用于对象或数组复杂响应式数据处理

2022-年终总结-忙碌的一年

2021-又是一年告别时

VueJs中的ref函数

VueJs中setup的使用(下)

如何解决chrome浏览器显示您要访问的是诈骗网站解决办法

点击左下角查看更多

VueJs中的reactive函数相关推荐

  1. Vue3学习之第二节:ref函数、reactive函数

    一.ref 函数 作用:定义一个响应式的数据. 示例: <template><div>{{ name }}</div> </template><s ...

  2. vuejs中 vmode_在VueJS中发现封闭的力量

    vuejs中 vmode By Fabian Hinsenkamp 费边·辛森坎普(Fabian Hinsenkamp) Today's frontend technology landscape r ...

  3. 如何在函数式编程中存在时间函数?

    本文翻译自:How can a time function exist in functional programming? I've to admit that I don't know much ...

  4. python中plot不能显示标签_python 2: 解决python中的plot函数的图例legend不能显示中文问题...

    问题: 图像标题.横纵坐标轴的标签都能显示中文名字,但是图例就是不能显示中文,怎么解决呢? 解决: plt.figure() plt.title(u'训练性能', fontproperties=fon ...

  5. Day 04-常用Composition API_ref reactive 函数

    目录 1.ref函数 2.reactive函数 3.reactive对比ref 1.ref函数 作用: 定义一个响应式的数据:  语法: const xxx = ref(initValue) 创建一个 ...

  6. vue3 reactive函数用法

    reactive的用法与ref的用法相似,也是将数据变成响应式数据,当数据发生变化时UI也会自动更新.不同的是ref用于基本数据类型,而reactive是用于复杂数据类型,比如对象和数组 例如:定义一 ...

  7. vuejs中如何实现三级路由并刷新页面时保持当前路由激活状态

    虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 如果不知道如 ...

  8. OpenCV 相机校正过程中,calibrateCamera函数projectPoints函数的重投影误差的分析

    OpenCV 校正过程中,calibrateCamera函数的ret和重投影误差的分析 OpenCV对相机进行校正的过程中,校正返回值retval和重投影误差的计算公式表示和分析. OpenCV 校正 ...

  9. Iar环境c语言调用汇编函数,如何在IAR EWARM中通过内联汇编程序在另一个模块中调用C函数?...

    我在硬故障处理程序中有一些程序集.程序集基本上是为了传递当前堆栈指针作为参数(在R0中).它看起来像这样...如何在IAR EWARM中通过内联汇编程序在另一个模块中调用C函数? __asm(&quo ...

最新文章

  1. Android 10 新增的功能
  2. Android开发究竟该如何学习,重难点整理
  3. python excel 自动化-简直出神入化,教你用Python控制Excel实现自动化办公
  4. HTML、JSP、Servlet中的相对路径和绝对路径 页面跳转问题
  5. logstash 利用drop 丢弃过滤日志
  6. mysql 备份如何使用_如何使用命令来备份和还原MySQL数据库
  7. python 逻辑回归 复杂抽样_如何用Python进行抽样?
  8. 先学python再学c_初学者Python和C先学哪个好?
  9. 多普勒优化的非匹配滤波器
  10. 《华为研发》阅读 - 15 (分解“满汉全席”,“先谋而后动”)
  11. Element UI快速入门
  12. 硬盘分区表错误与解决办法
  13. 【服务器搭建个人网站】附:接入的服务商 以及 安全评估报告该如何填写?
  14. 当女程序员遇到了问题......太真实了
  15. 机器学习笔记——神经网络与深度学习
  16. Installation Installing SDKMAN
  17. 小程序wx.downloadFile下载pdf并保存
  18. 单点自平衡立方体相当于有几个自由度?自平衡自行车有几个自由度?独轮车有几个自由度?
  19. mybatis-plus使用注意事项
  20. ThinkSNS/ThinkSNS后台应用管理

热门文章

  1. Java向word文档中添加水印
  2. 图解HTTP学习_day11
  3. 计算机网络:IP地址
  4. 从网络安装debian到使用中遇到的问题
  5. android音频文件存放目录,Android系统声音文件目录
  6. android drawtext 方法,8.2.13 drawText方法:绘制字符串
  7. JAVA分页代码实例
  8. Google搜索时如何在新标签页打开搜索结果
  9. latex伪代码添加注释_【其他】如何用写代码的方式进行文字编辑 Markdown 的简明教程...
  10. DOSBox+MASM搭建汇编环境