VueJs中的reactive函数
前言
一个基本类型的数据,想要变成响应式数据,那么需要通过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函数相关推荐
- Vue3学习之第二节:ref函数、reactive函数
一.ref 函数 作用:定义一个响应式的数据. 示例: <template><div>{{ name }}</div> </template><s ...
- vuejs中 vmode_在VueJS中发现封闭的力量
vuejs中 vmode By Fabian Hinsenkamp 费边·辛森坎普(Fabian Hinsenkamp) Today's frontend technology landscape r ...
- 如何在函数式编程中存在时间函数?
本文翻译自:How can a time function exist in functional programming? I've to admit that I don't know much ...
- python中plot不能显示标签_python 2: 解决python中的plot函数的图例legend不能显示中文问题...
问题: 图像标题.横纵坐标轴的标签都能显示中文名字,但是图例就是不能显示中文,怎么解决呢? 解决: plt.figure() plt.title(u'训练性能', fontproperties=fon ...
- Day 04-常用Composition API_ref reactive 函数
目录 1.ref函数 2.reactive函数 3.reactive对比ref 1.ref函数 作用: 定义一个响应式的数据: 语法: const xxx = ref(initValue) 创建一个 ...
- vue3 reactive函数用法
reactive的用法与ref的用法相似,也是将数据变成响应式数据,当数据发生变化时UI也会自动更新.不同的是ref用于基本数据类型,而reactive是用于复杂数据类型,比如对象和数组 例如:定义一 ...
- vuejs中如何实现三级路由并刷新页面时保持当前路由激活状态
虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 如果不知道如 ...
- OpenCV 相机校正过程中,calibrateCamera函数projectPoints函数的重投影误差的分析
OpenCV 校正过程中,calibrateCamera函数的ret和重投影误差的分析 OpenCV对相机进行校正的过程中,校正返回值retval和重投影误差的计算公式表示和分析. OpenCV 校正 ...
- Iar环境c语言调用汇编函数,如何在IAR EWARM中通过内联汇编程序在另一个模块中调用C函数?...
我在硬故障处理程序中有一些程序集.程序集基本上是为了传递当前堆栈指针作为参数(在R0中).它看起来像这样...如何在IAR EWARM中通过内联汇编程序在另一个模块中调用C函数? __asm(&quo ...
最新文章
- Android 10 新增的功能
- Android开发究竟该如何学习,重难点整理
- python excel 自动化-简直出神入化,教你用Python控制Excel实现自动化办公
- HTML、JSP、Servlet中的相对路径和绝对路径 页面跳转问题
- logstash 利用drop 丢弃过滤日志
- mysql 备份如何使用_如何使用命令来备份和还原MySQL数据库
- python 逻辑回归 复杂抽样_如何用Python进行抽样?
- 先学python再学c_初学者Python和C先学哪个好?
- 多普勒优化的非匹配滤波器
- 《华为研发》阅读 - 15 (分解“满汉全席”,“先谋而后动”)
- Element UI快速入门
- 硬盘分区表错误与解决办法
- 【服务器搭建个人网站】附:接入的服务商 以及 安全评估报告该如何填写?
- 当女程序员遇到了问题......太真实了
- 机器学习笔记——神经网络与深度学习
- Installation Installing SDKMAN
- 小程序wx.downloadFile下载pdf并保存
- 单点自平衡立方体相当于有几个自由度?自平衡自行车有几个自由度?独轮车有几个自由度?
- mybatis-plus使用注意事项
- ThinkSNS/ThinkSNS后台应用管理
热门文章
- Java向word文档中添加水印
- 图解HTTP学习_day11
- 计算机网络:IP地址
- 从网络安装debian到使用中遇到的问题
- android音频文件存放目录,Android系统声音文件目录
- android drawtext 方法,8.2.13 drawText方法:绘制字符串
- JAVA分页代码实例
- Google搜索时如何在新标签页打开搜索结果
- latex伪代码添加注释_【其他】如何用写代码的方式进行文字编辑 Markdown 的简明教程...
- DOSBox+MASM搭建汇编环境