VueJs中的reactive函数

news2024/9/24 5:23:56

前言

一个基本类型的数据,想要变成响应式数据,那么需要通过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.$delete
      this.$delete(this.person,'name');
      // 或者方法2,使用delete
      Vue.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则用于对象或数组复杂响应式数据处理

c5f9f340df80d3512cf6fe0164d6389d.jpeg

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


a48c09c0a65ce64b766fc1f25006f105.jpeg

2021-又是一年告别时


93dce2f47794b027010bb914596f71c9.jpeg

VueJs中的ref函数


b6c361f71ce230660b32bcb515371ac9.jpeg

VueJs中setup的使用(下)


5e4055246d8db08eb1bf107869d2f495.jpeg

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

点击左下角查看更多

5da4839b77834c9d1df179c7d3441794.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/131999.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一个DevOps/SRE/运维的2022年碎碎语

人们常说:情商高的人会说话。实际上他们的意思是对人说人话,对鬼说鬼话,这样的人才有前途。很长时间里,我一直以为我无法理解他们为什么要推崇心口不一。后来,我知道了。我不是不理解。我只是不服气。这样的”不服气“…

box-shadow 高阶玩法:纯 CSS 画蒙娜丽莎和粒子星空

想必写过 CSS 的同学都用过 box-shadow,它可以给元素设置阴影,增加立体效果。 比如说这样: 但它能做的可不只是阴影,还可以用来做出很多有趣的效果: 比如画蒙娜丽莎: 画星空: 这些效果都是 bo…

尚医通-医院查询接口-上传科室接口(十九)

目录 (1)医院查询接口-功能实现 (2)上传科室接口-功能实现 (1)医院查询接口-功能实现 接口文档: 4.4.查询医院 医院信息 4.4.1.提交地址 http://localhost/api/hosp/hospital/show 在ApiC…

《东晋门阀政治》

《东晋门阀政治》 关于作者 田余庆,北京大学历史系教授,国务院古 籍整理出版规划小组成员,是魏晋南北朝 政治史专家。他在学术界拥有重要的地位,参加编著的《中国史纲要》曾获国家 教委特等奖。著有《秦汉魏晋史探微》 《拓跋史…

ubuntu 22.04上vim-plug插件管理器,相关插件与ROS2的安装

前言 最近,新配置了一版虚拟机,因为学校已经配置好环境的虚拟机忘了带回来,我还想系统的学习一下ROS,并将其用于机械臂的控制,因此用了新的方式配置了vim,并将树莓派raspberry buster系统配置上了ROS1的环…

Flink系列Table API和SQL之:滚动窗口、滑动窗口、累计窗口、分组聚合

Flink系列Table API和SQL之:窗口一、窗口(Window)二、分组窗口(Group Window)三、窗口表值函数(Windowing TVFs)1.滚动窗口(TUMBLE)2.滑动窗口(HOP)3.累计窗口(CUMULATE)四、分组聚合五、分组聚合实现代码六、分组窗口聚合代码实现七、窗口聚合:滚动窗口…

【SCL】博图SCL应用之音乐喷泉

使用Scl语言编写博图应用:音乐喷泉 文章目录 目录 一、音乐喷泉 1.控制要求 2.I/O分配 3.编写程序 4.效果和完整代码 二、装配流水线模拟控制(练习) 1.控制要求 2.场景 前言 承接上文,这里写一下上一篇的练习题 音乐喷泉应用案…

使用Typora+PicGo+SM.MS实现本地博客图片自动上传

使用TyporaPicGoSM.MS实现本地博客图片自动上传 Typora:一款Markdown 编辑器 PicGo: 一个用于快速上传图片并获取图片 URL 链接的工具. SM.MS: 一个图床网站,注册后有5G免费空间 为什么要让本地图片自动上传 对于一个随时随刻都有可能在文章中贴代码的计…

快来领取你的JavaScript正则表达式速查表

如果我们想对字符串进行相关(增、删、改、查、检索)操作,就可以用接下来的正则表达式实现 什么是正则表达式 正则表达式是用于匹配字符串中字符组合的模式正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本…

家装中,你最后悔的事是什么?上海极家装修公司简介!

家装中,你最后悔的事是什么?上海极家装修公司简介!接触过很多业主,就没有不后悔的!至于原因,因为总会出现各种“考虑不周”,有些真的是失之毫厘差之千里! 下面上海极家装修公司简介!…

Cadence每日一学_12 | 使用 Padstack Editor 制作贴片焊盘和通孔焊盘

最近在学习小马哥的Cadence课程,该系列课程为学习笔记:使用Cadence Allegro绘制小马哥DragonFly四轴飞行器(STM32F4主控)PCB四层板教程。 文章目录一、获取焊盘封装尺寸的途径二、Padstack Editor三、绘制贴片焊盘(以电阻焊盘为例&#xff09…

Odoo 16 企业版手册 - 库存管理之产品类别

产品类别 您可以使用Odoo 库存模块中提供的产品类别功能对产品进行分类。为了执行各种产品操作,必须在Odoo中定义产品类别。Odoo将使产品更容易找到,因为它允许您按产品类别进行筛选。用户可以从库存模块的「配置」菜单访问「产品类别」窗口,…

【Python】sklearn机器学习之Birch聚类算法

文章目录基本原理sklearn调用基本原理 BIRCH,即Balanced Iterative Reducing and Clustering Using Hierarchies,利用分层的平衡迭代规约和聚类,特点是扫描一次数据就可以实现聚类, 而根据经验,一般这种一遍成功的算…

02 elf 的 binary 解析

前言 需求来自于 linux binary 的执行分析, 以及一些反编译工具的实现 比如 readelf, hopper disassemble 什么的 主要的目的是 更加详细了解 elf 的文件格式 为 后续的一些 理解做准备 elf 解析 elf 文件主要分为 四个部分 elfHeader, programHeaders, segments, …

2022年度盘点|聚焦运维服务,云智慧的高光时刻

回首2022,从IE 浏览器退役到AIGC 火遍全球,每一次科技的兴衰演进都打破着技术的新边界。与此同时,随着各行业数据规模爆发式地增长,云智慧作为国内全栈智能运维解决方案服务商,企业数字化地加速转型也为其带来了更多的…

Hibernate validator注解及Spring Boot自定义Hibernate Validator注解校验(超级详细)

一 Hibernate validator是什么 验证数据是贯穿整个应用层(从表示层到持久层)的常见任务。通常在每一层中都需要实现相同的验证逻辑,这样既耗时又容易出错。为了避免这些验证的重复,开发认原经常将验证逻辑直接捆绑到Model域中&…

1.9 基础综合案例|pyechart第三方包

文章目录json数据格式pyecharts模块介绍pyecharts快速入门数据处理这里使用比较经典的pyechart的第三方包。json数据格式 json是一种轻量级的数据交互形式。可以按照json指定的格式去组织和封装数据。或者这么说本质上json就是一个带有特定格式的字符串。 主要功能&#xff1…

【金猿案例展】正官庄——全渠道会员数据治理驱动商业增长

‍珍岛集团案例本项目案例由珍岛集团投递并参与“数据猿年度金猿策划活动——《2022大数据产业年度创新服务企业》榜单/奖项”评选。‍数据智能产业创新服务媒体——聚焦数智 改变商业随着商业品牌的全渠道裂变式发展,对DTC直营会员为中心的综合数据运营提出了新的…

【自学Java】Java基本数据类型

Java基本数据类型 Java基本数据类型 Java 基本数据类型如下表: 序号数据类型大小/位可表示的数据范围默认值1long(长整数)64-9223372036854775808~92233720368547758070L2int(整数)32-2147483648&#x…

设置 MYSQL 数据库编码为 utf8mb4

utf-8编码可能2个字节、3个字节、4个字节的字符,但是MySQL的utf8编码只支持3字节的数据,而移动端的表情数据是4个字节的字符。如果直接往采用utf-8编码的数据库中插入表情数据,java程序中将报SQL异常: java.sql.SQLException: Inc…