Vue 3中数组与对象

一、Vue 3响应式原理与基础操作

1. 响应式系统实现

Vue 3使用Proxy替代了Vue 2中的Object.defineProperty来实现响应式系统,带来了以下优势:

  • 全面性‌:可以监听对象的新增属性和删除属性

  • 高效性‌:无需递归遍历整个对象树,只有在访问某个属性时才会触发代理

  • 支持数组操作‌:可以直接监听数组的变化,例如push、splice等方法

核心API包括:

  • reactive‌:用于创建响应式对象,适用于复杂数据结构

  • ref‌:用于创建包含value属性的响应式对象,适用于基本数据类型

  • toRefs‌:将响应式对象转换为普通对象的响应式引用

2. 数组操作最佳实践

Vue 3对数组的原生变异方法进行了包裹,使得这些操作能够触发视图更新:

const arr = reactive([1, 2, 3]);arr.push(4);  // 正确方式

应避免的操作:

直接通过索引修改数组元素:arr[0] = 'newValue' (不会触发更新)

直接修改数组长度:arr.length = newLength (不会触发更新)

二、对象操作与动态属性管理

1. 对象属性操作

在Vue 3中,可以直接修改响应式对象的属性:

const form = reactive({ file: "", fileArr: [] });form.file = "newFile.txt";  // 正确方式


批量更新对象属性的方法:

// 使用Object.assignObject.assign(form, { file: "newFile.txt", fileArr: ["file1.txt"] });// 使用展开运算符form = { ...form, ...{ file: "newFile.txt" } }:ml-citation{ref="13" data="citationList"}

2. 动态添加属性

Vue 3中动态添加属性的正确方式:

const maskingConfig = reactive({} as any);maskingConfig.newProperty = "value";  // 直接添加属性:ml-citation{ref="27" data="citationList"}// 或者使用Reflect.setReflect.set(val, 'middle', middle):ml-citation{ref="26" data="citationList"}

三、深拷贝与响应式数据

1. 深拷贝方法

在Vue 3中实现深拷贝的几种方式:

方法优点缺点适用场景
JSON.parse(JSON.stringify())简单易用无法拷贝函数、循环引用简单数据结构
Lodash的_.cloneDeep功能强大需要引入外部库复杂数据结构
递归函数可定制性强需要自行实现特殊需求场景

2. 保持响应式的深拷贝

如果需要保持响应式特性,可以使用toRefs:

const original = reactive({ count: 0 });const copy = toRefs(original);  // 保持响应式:ml-citation{ref="20" data="citationList"}

四、性能优化技巧

1. 数组性能优化

  • 对于大型数组,考虑使用shallowRefmarkRaw来避免不必要的响应式转换

  • 避免在计算属性中修改状态或产生副作用

  • 使用v-for时始终提供唯一的key

2. 对象性能优化

  • 仅将需要响应式更新的数据标记为响应式

  • 使用computed属性基于其依赖的响应式数据进行缓存

  • 优化深度监听,只监听必要的属性变化


五、常见问题与解决方案

1. 响应式失效场景

  • 直接整体替换reactive对象‌:obj = {a:2} (失去响应式)

    • 解决:使用Object.assign(obj, {a:2})

  • 数组直接赋新数组引用‌:arr = [4,5,6] (失效)

    • 解决:arr.splice(0, arr.length,4,5,6)

  • 深层嵌套对象修改不触发更新

    • 解决:确保使用reactive创建嵌套对象,或改用watchEffect自动追踪依赖

2. 嵌套对象响应式问题

Vue 3的Proxy在处理深层嵌套对象时可能存在缺陷:

const proxyVal = reactive({   info: {     age: 18,    deep: { desc: '...' }   } });// 直接访问proxyVal.info.age可能不会触发深层代理:ml-citation{ref="47" data="citationList"}

解决方案:

直接访问reactive定义的变量,而不是使用解构赋值

使用toRefs方法将响应式对象转化为普通对象的响应式属性

在解构赋值时使用拷贝来避免数据丢失


标签:

相关文章

《山海经》中的一卷--北山经

《北山经》概括性翻译概述一、引言《北山经》详细描述了北方的山川地理,以及在这些山川中栖息的奇异生物和丰富的自然资源。这些描述不仅展示了古人对北方自然界的深入观察与丰富想象,也反映了他们对自然界的敬畏与...

前端消息队列技术解析

一、核心应用场景‌异步任务处理‌用户行为日志上报、实时通知推送等场景,通过消息队列实现非阻塞式通信,避免页面卡顿‌典型代码模式对比:// 传统同步模式(阻塞页面) async f...

axure使用的故事

‌Axure 是一款专注于原型设计与交互逻辑构建的专业工具,被广泛用于用户界面(UI)和用户体验(UX)设计领域。‌林风与他的伙伴们,在经历了无数次江湖历险后,决定利用现代科技手段来更有效地规划和管理...

php介绍

PHP(Hypertext Preprocessor)是一种广泛使用的开源服务器端脚本语言,主要用于Web开发。以下是关于PHP的关键信息:🔵 基础特性‌语言定位‌专为Web设计,可嵌入HTML,支持...

前端错误集合

⚠️ ‌一、核心运行时错误类型‌‌SyntaxError(语法错误)‌‌原因‌:代码不符合 JavaScript 语法规则(如变量命名不合规、括号缺失等)‌案例‌:var1a = 10;(数字开头的变...

弱类型与强类型

弱类型与强类型是编程语言类型系统的两种重要分类,主要区别体现在类型转换的严格性和处理方式上:1. 核心区别‌强类型语言‌:要求显式类型声明,禁止隐式类型转换类型错误会在编译时或运行时直接报错(如Jav...