目录
直击Vue2/3watch的底层逻辑,字符串长度对侦听效率的影响
一、Vue 2的底层原理
二、Vue 3的底层原理
三、基础类型性能消耗
四、数据变化比较原理
1、Vue 2 中的引用类型比较
2、Vue 3 中的引用类型比较
3、字符串比较(基础类型比较)
4、性能影响
5、代码示例
五、总结
作者:watermelo37
涉及领域:Vue、SpingBoot、Docker、LLM、python等
-------------------------------------------------------------------------------------------------------------------------
--------------------------温柔地对待温柔的人,包容的三观就是最大的温柔。--------------------------
-------------------------------------------------------------------------------------------------------------------------
直击Vue2/3watch的底层逻辑,字符串长度对侦听效率的影响
在Vue 2 和 Vue 3 中,watch 实现的底层原理有一些不同,但它们都基于 Vue 的响应式系统。
一、Vue 2的底层原理
在 Vue 2 中,响应式系统使用的是基于 Object.defineProperty 的实现。这种方式的 watch 主要通过以下步骤实现:
- 初始化时拦截属性:Vue 在初始化数据对象时,会递归遍历数据对象的每一个属性,并使用Object.defineProperty 拦截属性的访问和赋值操作。
- 依赖收集:当访问某个属性时,会将当前的 watcher(观察者)记录为该属性的依赖。在赋值时,会触发依赖的更新。
- 触发更新:当属性的值发生变化时,会通知相关的 watcher,并调用它们的回调函数。
二、Vue 3的底层原理
在 Vue 3 中,响应式系统进行了重写,采用了基于 Proxy 的实现。这种方式的 watch 主要通过以下步骤实现:
- 使用 Proxy 拦截:Vue 3 使用 Proxy 来拦截对数据对象的访问和修改操作。Proxy 可以直接拦截对对象的操作,而不需要递归遍历每个属性。
- 依赖收集和触发更新:与 Vue 2 类似,当访问某个属性时,会进行依赖收集。当属性值变化时,会通知相关的 watcher,并调用它们的回调函数。
三、基础类型性能消耗
由于 watch 对字符串的处理是将其作为一个整体来对待,因此字符串的长度对性能的影响主要体现在两个方面:
- 值比较:在某些情况下,Vue 需要比较新旧值以确定是否发生变化。对于长字符串,这种比较操作可能会稍微增加性能消耗。
- 内存占用:长字符串在内存中的占用会更多,可能会增加垃圾回收的开销。
然而,实际应用中,这种性能差异通常是可以忽略的(这是一个O(1) 复杂度的运算),除非在非常频繁的字符串变化场景下,字符串长度非常大(例如数百万字符)。
四、数据变化比较原理
1、Vue 2 中的引用类型比较
在 Vue 2 中,当数据发生变化时,Vue 会将新值与旧值进行比较。比较的过程主要在 watcher 内部完成。
-
浅比较:默认情况下,Vue 进行浅比较,即仅比较对象或数组的引用是否发生变化。这种方式效率较高,但对于嵌套对象或数组的深层变化无法检测到。
-
深比较:如果 watch 选项设置了
deep: true
,Vue 会进行深度递归比较。这样可以检测到嵌套对象或数组内部的变化,但会增加性能开销。
2、Vue 3 中的引用类型比较
在 Vue 3 中,响应式系统经过了重构,基于 Proxy
的实现使得值比较的过程有所简化和优化。
-
浅比较:与 Vue 2 类似,默认情况下进行浅比较,只检测对象或数组的引用变化。
-
深比较:如果 watch 选项设置了 deep:true,Vue 3 也会进行深度递归比较,检测嵌套对象或数组的内部变化。
3、字符串比较(基础类型比较)
对于字符串类型的数据,Vue 的值比较相对简单,因为字符串是基本数据类型,可以直接进行值比较。
-
引用比较:对于基本数据类型(如字符串、数字、布尔值等),Vue 直接比较它们的值。这种比较是 O(1) 的操作,因此对于字符串长度不敏感。
-
深比较:不适用于基本数据类型,因为字符串是不可变的值类型,不涉及对象的嵌套结构。
4、性能影响
-
浅比较性能:浅比较效率很高,因为它只比较引用或值。字符串的长度对浅比较性能没有影响。
-
深比较性能:深比较涉及递归检查对象的每一个属性和嵌套结构,对于复杂的嵌套对象会有一定的性能开销。对于字符串,不会进行深度比较,因此字符串长度对深比较也没有影响。
5、代码示例
以下是 Vue 3 中一个简单的 watch 示例,演示如何比较字符串:
import { reactive, watch } from 'vue';const state = reactive({message: 'Hello, Vue 3!'
});watch(() => state.message, (newVal, oldVal) => {console.log('Message changed from', oldVal, 'to', newVal);
});// 修改字符串,触发 watch 回调
state.message = 'Hello, World!';
在上述代码中,当 state.message 变化时,watch 回调会被触发,并且会输出新旧值。对于字符串类型,Vue 会直接比较新旧值,确定是否发生变化。
五、总结
Vue 中的 watch 实现会在数据变化时进行值比较。对于字符串,比较过程是简单高效的值比较,而不会受字符串长度影响。除非在非常特殊的场景下频繁处理超长字符串,否则性能差异可以忽略不计。
只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
更多优质内容,请关注:
分片上传技术全解析:原理、优势与应用(含简单实现源码)
浏览器渲染揭秘:从加载到显示的全过程
你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解
通过array.filter()实现数组的数据筛选、数据清洗和链式调用
el-table实现动态数据的实时排序,一篇文章讲清楚elementui的表格排序功能
shpfile转GeoJSON且控制转化精度;如何获取GeoJSON?GeoJson结构详解
通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式等
极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图
Mapbox添加行政区矢量图层、分级设色图层、自定义鼠标悬浮框、添加天地图底图等
管理数据必备!侦听器watch用法详解