详解 Vue3 中如何使用 Proxy 来实现响应式的技术~

news2024/11/24 1:55:38

详解 Vue3 中如何使用 Proxy 来实现响应式的技术~

  • 写在前面
  • 剖析 Vue2 中是如何实现响应式的
    • Vue2 的响应式存在什么问题?
  • Vue3 响应式
    • 一、`ref` 函数
    • 二、`reactive` 函数
    • `reactive` 响应式原理 - Proxy
    • Vue3 中的响应式解决了 Vue2 中存在的问题

写在前面

Vue3 中的响应式原理以及实现机制,相较于 Vue2 中,有了很大的升级和性能提升。而且优化了很多问题,值得学习和研究!

学习和理解 Vue3 中的响应式原理和实现,对再项目实战中的使用,有很大的帮助;遇到问题时,能发现问题的关键所在。

剖析 Vue2 中是如何实现响应式的

我们知道,在 Vue2 中,Vue 是使用 Object.defineProperty 来实现响应式的。关于 Object.defineProperty,一个简单的例子:

// 源数据
let person = {
  name: '张三',
  age: 18
}

// 模拟 Vue2 中实现响应式
let p = {}
Object.defineProperty(p, 'age', {
  // enumerable:true, // 控制属性是否可以枚举,默认值是false
  // writable:true, // 控制属性是否可以被修改,默认值是false
  // configurable:true, // 控制属性是否可以被删除,默认值是false

  //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
  get(){
	console.log('【检测到了】有人读取age属性了,我可以做一些事情了,这里是响应式的关键')
	return person.number
  },
  //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
  set(value){
	console.log('【检测到了】有人修改了age属性,且值是:', value)
	person.age = value
  }
})

// ...

上面的例子中,使用了 Object.definePropertypage 属性设置了 setget 方法。

这样,以后,page 属性发生修改或者取值的时候,就能监测到了。

同理,p 中的其他属性,也是这样来实现响应式的,Vue2 中就是这样做的。

Vue2 的响应式存在什么问题?

1、新增属性、删除属性、界面不会更新

Vue2 的解决方法:this.$set(object, 'key', value)this.$delete(object, 'key')

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

Vue2 的解决方法:this.$set(object, index, value)

Vue3 响应式

一、ref 函数

在 Vue3 中,定义基本数据类型的响应式,我们使用 ref 函数。

let sum = ref(0)

console.log(sum.value)

return {
  sum
}

ref 函数:

  • 接受的数据可以是:基本类型、也可以是对象类型;
  • 基本类型的数据是:响应式依然是靠 Object.defineProperty()getset 完成的;
  • 对象类型的数据:内部【求助】了 Vue3 中的一个新函数 —— reactive 函数;

二、reactive 函数

定义一个【引用类型】的响应式数据(基本类型不要用它,要用 ref 函数)

let personInfo = reactive({
	name: '张三',
	age: 11,
	jobs: ['前端', '后端', '设计']
})
  • reactive 定义的响应式数据是“深层次的”。
  • 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作。

reactive 响应式原理 - Proxy

  • 通过 Proxy(代理) 拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等。
  • 通过 Reflect(反射)对源对象的属性进行操作。
let proxy = new Proxy(data, {
  // 拦截读取属性值
  get (target, prop) { // target:原对象; prop:读取的属性
    console.log(`监听到了属性值${prop}被读取`)
    return Reflect.get(target, prop)
  },
  // 拦截设置属性值或添加新属性
  set (target, prop, value) { // target:原对象; prop:要修改/增加的属性  value:值
    //target[prop] = value
    console.log(`监听到了属性值${prop}发生变化`)
    return Reflect.set(target, prop, value)
  },
  // 拦截删除属性
  deleteProperty (target, prop) {
    //return delete target[prop]
    console.log(`监听到了属性值${prop}被删除`)
    return Reflect.deleteProperty(target, prop)
  }
})

// proxy 就是源数据 data 的响应式代理对象
proxy.name = 'tom' // 触发监听
let age = proxy.age // 触发监听
delete proxy.name // 触发监听

这种方式实现的响应式,相较于之前的 Object.defineProperty,在代码实现了,简洁优雅了很多。

Proxy 是 ES6 中新提出的方案,也是 JS 语言后面发展的方向,在 JS 语言后续的发展上,如果有改动或者新的提议,也是会在 Proxy 上面来优化,而不太会再优化之前的 Object.defineProperty 方案了。

Vue3 中的响应式解决了 Vue2 中存在的问题

1、新增属性、删除属性、界面会更新了

proxy.page = 1
VM314:15 监听到了属性值page发生变化

新增一个 page 属性时,也会触发 set() 函数了。

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

—————————— 【正文完】——————————

前端学习交流群,想进来面基的,可以加群: 832485817,685486827;
前端顶级学习交流群(一) 前端顶级学习交流群(二)

写在最后: 约定优于配置 —— 软件开发的简约原则

——————————【完】——————————

我的:
个人网站: https://neveryu.github.io/neveryu/
Github: https://github.com/Neveryu
微信: miracle421354532

更多学习资源请关注我的微信…好吗

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

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

相关文章

C++:STL:常见容器:stack,queue, list

一:stack容器 1.1: stack基本概念 概念:stack是一种先进后出 (First in last out FILO)的数据结构,它只有一个出口。 栈中: 1:只有栈顶的元素才可以被外界使用,因此栈不允许有遍历…

从FrameDebugger看Unity渲染

从FrameDebugger看Unity渲染(一) Unity如何渲染一个3D2D的游戏画面,今天通过FrameDebugger来看下Unity内置渲染管线的渲染策略, 后续再出一些URP渲染管线相关的文章。 对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白&#xff0c…

MyBatis 实现复杂 Sql 查询

resultMap 结果映射 resultMap 元素是 MyBatis 中最重要最强大的元素&#xff0c;之前所写的 sql 语句&#xff0c;返回值都是简单的基本数据类型或者某一个实体类&#xff0c;比如下面这段 sql 返回的就是最简单的 User 类型。 <select id"getUserById" result…

微信HOOK 协议接口 实战开发篇 3.收发文本消息 附详细步骤

前言&#xff1a;本次文章附带详细的HOOK步骤&#xff0c;感兴趣可以尝试一番 使用了之前文章提到的字符搜索法 接收消息 1.OD打开微信&#xff0c;点击e&#xff0c;进入模块列表 2.双击wechatwin模块进入汇编代码页面 3.右键菜单&#xff0c;选择如图示选项 4.进入字符页…

【 uniapp - 黑马优购 | tabBar】如何创建和配置标签栏

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;讨厌编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

zabbix监控redis修正nodata问题

之前根据网上的资料尝试监控redis&#xff0c;完成后编写了文档。 https://blog.csdn.net/bigwood99/article/details/128404063 这几天观察数据&#xff0c;发现没有数据被采集。 在图标中显示no data。 检查模板中item和graphs设置&#xff0c;发现key中没有使用引号。 …

修复U盘【笔记】

修复U盘【笔记】前言参考修复U盘问题0.芯片精灵查看1.用APTool软件擦除量产信息2.用CBMTool量产U盘结果我的版本最后前言 以下内容源自网络 仅供学习交流使用 参考 总体步骤&芯片精灵下载&#xff1a;https://www.xpwin7.com/jiaocheng/25627.html 资源下载网址来源&am…

组织上线 | 资源共享,协作自如

新功能&#xff5e;&#xff01;期待已久的组织协作上线啦&#xff01; 上线后支持在组织下创建镜像&#xff0c;组织成员可查看、拉取镜像&#xff0c;快速实现镜像资源共享&#xff0c;组织高效协同。 具体怎么操作呢&#xff1f;跟我一起来看一下吧&#xff5e; 创建组织 …

Pandas计算历史均值

在用Python进行时间序列分析时&#xff0c;我们可能经常需要计算历史的一些特征。一般会使用rolling()函数&#xff0c;这里介绍一下计算包括当前行的历史特征和不包括当前行的历史特征 1. 包括当前行 这里先简单介绍一下rolling()函数 pandas.DataFrame.rolling官方文档 Dat…

数据库,计算机网络、操作系统刷题笔记19

数据库&#xff0c;计算机网络、操作系统刷题笔记19 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle…

Vue后台项目的记录 (二)

1、品牌静态管理组件 表单 分页器 2、品牌列表展示 创建相关接口文件 获取品牌管理数据的模块 统一接口管理 在main.js中引入&#xff0c;之后在任意组件中就可以使用了 发请求&#xff0c;获取品牌列表的接口 展示数据 current-change"handlecurrentchange curren…

贤鱼的刷题日常(数据结构队列学习)-2406:Card Stacking--题目详解

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;例题讲解2406:Card Stacking ✅创作者&#xff1a;贤鱼 ⏰预计时间&#xff1a;25分钟 &#x1f389;个人主页&#xff1a;贤鱼的个人主页 &#x1f525;专栏系列&#xff1a;c &#x1f341;贤鱼的个人社区&#xff0c;欢…

LabVIEW如何减少下一代测试系统中的硬件过时5

LabVIEW如何减少下一代测试系统中的硬件过时5 Steps to Replace Instruments Performance Requirements The important consideration to make when replacing instruments isthat the replacements must meet your requirements, usually by having equal orbetter measure…

6.1 微服务-Redis

6.1.1 Redis 6.1.1.1 前言 前面使用到的mysql数据库会出现以下问题 由于用户量增大&#xff0c;请求数量也随之增大&#xff0c;数据压力过大 多台服务器之间数据不同步 多台服务器之间的锁&#xff0c;已经不存在互斥性了。 6.1.1.2 Redis 6.1.1.2.1 什么是Redis Redi…

电脑屏幕录制怎么弄,简单好用的3种电脑录屏方法

平时工作或者学习都需要使用电脑进行录屏操作&#xff0c;比如录制线上网课、游戏画面、教学课程录屏等等。电脑屏幕录制怎么弄&#xff1f;可以使用专业录屏软件或者是电脑自带的屏幕录制功能来录屏&#xff1b;今天给大家分享3款简单好用的电脑录屏方法&#xff1b;无论是录制…

2022知识付费小程序源码升级版知识付费变现小程序独立后台版本源码+数据库和教程

知识付费小程序源码升级版主要功能简介&#xff1a; 本源码后台部分是thinkphp开发的&#xff0c;使用和二次开发都非常方便。 会员系统&#xff1a;用户登录/注册购买记录&#xff0c;收藏记录 基本设置&#xff1a;后台控制导航颜色&#xff0c;字体颜色&#xff0c;标题等…

软件测试面试话术 这样准备,让你成功拿到高薪offer

面试就是就是进入岗位前的临门一脚&#xff0c;如果因为准备不足而导致面试失败那可就亏大了&#xff01;因此&#xff0c;为了帮助大家提高面试成功率&#xff0c;尽快拿到高薪offer&#xff0c;我为你们准备了一套面试话术以及技巧&#xff0c;希望对即将参加软件测试面试的你…

MyBatis一级缓存和二级缓存

缓存的作用 在 Web 系统中&#xff0c;最重要的操作就是查询数据库中的数据。但是有些时候查询数据的频率非常高&#xff0c;这是很耗费数据库资源的&#xff0c;往往会导致数据库查询效率极低&#xff0c;影响客户的操作体验。于是可以将一些变动不大且访问频率高的数据&…

六、Java 13 新特性

六、Java 13 新特性 Java 13 已如期于 9 月 17 日正式发布&#xff0c;此次更新是继半年前 Java 12 这大版本发布之后的一次常规版本更新&#xff0c;在这一版中&#xff0c;主要带来了 ZGC 增强、更新 Socket 实现、Switch 表达式更新等方面的改动、增强。本文主要针对 Java 1…

开发检查测试参考文档整理

前言 【1】比起成为一名优秀的程序员&#xff0c;我更青睐于成为一名有价值的靠谱的员工。在企业工作中&#xff0c;我们既需要很好的去完成我们的日常需求&#xff0c;同时也需要去保证我们编写代码的质量&#xff0c;减少问题的发生&#xff0c;我们要去做靠谱的有责任心的员…