当前位置: 首页 > backend >正文

vue响应式原理——vue2和vue3的响应式实现区别

        Vue的核心功能点之一是响应式:Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM。

        简单的来说就是,页面的渲染效果会随着数据变化而变化,不用我们去手动操作DOM树进行数据变化后的渲染。为了实现这一目的,我们最简单的实现思路就是去监听每一个对象中的值,在我们获取或者更新这个值是插上一脚来操作DOM,此时,就可以通过函数去操作这个对象,以达到我们的目的。

vue2的响应式实现方法:defineProperty

        Object.defineProperty() 是 JavaScript 中的一个方法,用于直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。它提供了精细的控制能力,可以定义属性的特性(特性包括可枚举、可配置、可写性等),并可以定义 getter 和 setter,在属性被访问或者设置时执行自定义的行为。

        这里vue2的思路则为通过该方法来遍历对象,达到监听对象属性的目的,代码如下:

const obj = {a: 1,b: 2,c: {d: 3,e: 4,}
} as any//观察
const observer = (obj: any) => {for (const key in obj) {let temp = obj[key]if (typeof obj[key] === 'object') {observer(obj[key])} else {Object.defineProperty(obj, key, {get() {console.log('读取', key)return temp},set(val) {console.log('修改', key)temp = val}})}}
}observer(obj)obj.a;// 读取 a
obj.b = 3; // 修改 b
obj.c.d; // 读取 c.dobj.f = 5 // 新添属性 f 并修改 f

输出结果:

 

        这里我们可以发现, 我们用递归的方式来去对每个值进行了监听,但是对应后面新增的对象属性就没有相对性的监听效果,如果想进行监听,就需要对这个属性进行单独的处理:

const obj = {a: 1,b: 2,c: {d: 3,e: 4,}
} as any//观察
const observer = (obj: any) => {for (const key in obj) {let temp = obj[key]if (typeof obj[key] === 'object') {observer(obj[key])} else {Object.defineProperty(obj, key, {get() {console.log('读取', key)return temp},set(val) {console.log('修改', key)temp = val}})}}
}const set = (obj: any, key: string, value: any) => {obj[key] = valuelet temp = obj[key]if (typeof value === 'object') {observer(value)} else {Object.defineProperty(obj, key, {get() {console.log('读取', key)return temp},set(val) {console.log('修改', key)temp = val}})}
}observer(obj)obj.a;// 读取 a
obj.b = 3; // 修改 b
obj.c.d; // 读取 c.dset(obj, 'f', {g: 5
}) // 修改 fobj.f.g; // 读取 f

输出结果:

 vue3的响应式实现方法:Proxy

        Proxy 是 ES6 中新增的一个功能,它允许你在访问一个对象之前定义自定义行为。通过 Proxy,你可以创建一个代理对象来包裹目标对象,并可以拦截并重定义该对象的各种操作,如属性的读取、赋值、删除等操作,甚至可以自定义对象的行为。

       vue3使用的是Proxy来进行响应式操作的,这里就没必要将对象的所有属性进行遍历,而是使用哪个属性,则对哪个属性进行监听:

const obj ={a: 1,b: 2,c: {d: 3,e: 4,}
} as anyconst option = {get(target: any, key: any) {console.log('读取', key)//判断是否是对象if (typeof target[key] === 'object') {return new Proxy(target[key], option)}return target[key]},set(target: any, key: any, value: any) {console.log('设置', key, value)//判断是否是对象if (typeof value === 'object') {target[key] = new Proxy(value, option)return true}return true},
}const proxy = new Proxy(obj, option)proxy.a = 10; // 设置 a 10
proxy.a; // 读取 aproxy.c.f = 20; // 设置 c.f 20
proxy.c.f; // 读取 c.fproxy.c; // 读取 c

输出结果:

总结

        vue2和vue3的响应式操作相比,vue2需要遍历对象,且对于新的属性无法直接进行监听,而vue3使用代理对象就不会出现这个问题。

http://www.xdnf.cn/news/2624.html

相关文章:

  • 非结构化数据解析
  • wsl(8) -- 图形界面
  • 封装el-autocomplete,接口调用
  • Ubuntu安装brew
  • OSI 模型(开放系统互联模型)
  • FEKO许可安装
  • CCF推荐学术会议-C(网络与信息安全):SAC 2025
  • Python学习之路(六)-图像识别
  • 数字化转型的未来趋势:从工具到生态,聚焦生态合作、绿色转型与全球化布局
  • Vue3 Element Plus el-tabs数据刷新方法
  • 更快的图像局部修改与可控生成:Flex.2-preview
  • 航顺 芯片 开发记录 (一) 2025年4月27日19:23:32
  • 【博客系统】博客系统第二弹:实现博客列表接口
  • T检验、F检验及样本容量计算学习总结
  • 通过示例学习:连续 XOR
  • SpringBoot驾校报名小程序实现
  • 详细PostMan的安装和基本使用方法
  • 【SF】在 Android 显示系统中,图层合成方式 Device 和 Client 的区别
  • 文章记单词 | 第50篇(六级)
  • Zookeeper HA集群搭建
  • 昂瑞微蓝牙OM6621系列对比选型指南
  • 《代码整洁之道》第8章 边界 - 笔记
  • NCCL 通信与调试
  • Grok发布了Grok Studio 和 Workspaces两个强大的功能。该如何使用?如何使用Grok3 API?
  • 深度学习与SLAM特征提取融合:技术突破与应用前景
  • 深入解读:2025 数字化转型管理 参考架构
  • 视频HLS分片与关键帧优化深度解析
  • 2025 网络安全技术深水区探索:从 “攻防对抗” 到 “数字韧性” 的范式跃迁
  • VRRP与BFD在冗余设计中的核心区别:从“备用网关”到“毫秒级故障检测”
  • JavaScript中主动抛出错误的方法