vue3 computed(长文讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
在 Vue.js 开发中,vue3 computed 是一个核心概念,它帮助开发者高效地管理组件中的复杂逻辑。无论是计算属性的响应式更新,还是优化性能,vue3 computed 都提供了简洁且强大的解决方案。本文将从基础到进阶,结合实际案例,深入解析 vue3 computed 的工作原理、使用场景及常见误区,帮助开发者快速掌握这一工具。
一、基础概念与核心功能
1.1 什么是 vue3 computed?
vue3 computed 是 Vue3 中用于定义计算属性(Computed Property)的函数。它通过依赖追踪机制,自动根据相关数据的变化,重新计算并返回结果。与普通方法不同,vue3 computed 的值会被缓存,只有在相关响应式数据发生变化时才会重新计算,从而提升性能。
形象比喻:
可以将 vue3 computed 想象为厨房里的“配方”。例如,制作一道菜需要混合盐、糖和醋,只要这些原材料的量不变,最终的调味汁配方就不需要重新调配。只有当原材料变化时,才会重新按照配方制作。
1.2 基本语法与示例
在 Vue3 的 setup
函数中,通过 computed
函数定义计算属性:
import { ref, computed } from 'vue';
export default {
setup() {
const firstName = ref('John');
const lastName = ref('Doe');
// 定义计算属性
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`;
});
return {
firstName,
lastName,
fullName,
};
},
};
在模板中可以直接使用 {{ fullName }}
,它会根据 firstName
和 lastName
的变化自动更新。
二、响应式原理与内部机制
2.1 依赖追踪机制
vue3 computed 的核心是响应式系统。当计算属性函数被调用时,Vue3 会自动追踪其内部访问的响应式数据(如 ref
或 reactive
对象的属性)。这些数据被称为“依赖”。
图解流程:
- 当
fullName
被首次访问时,其内部会读取firstName
和lastName
的值。 - Vue3 将这两个值标记为
fullName
的依赖。 - 若
firstName
或lastName
发生变化,Vue3 会触发fullName
的重新计算。
2.2 缓存机制
计算属性的结果会被缓存,避免重复计算。例如,在模板中多次使用 {{ fullName }}
时,只有当依赖变化时,才会重新执行计算函数。
对比:
情况 | 计算属性(computed) | 普通方法(method) |
---|---|---|
依赖未变化时 | 返回缓存值,无需计算 | 每次调用都会重新执行函数 |
依赖变化时 | 重新计算并更新缓存 | 仍需手动触发或重新调用方法 |
三、实际案例与代码示例
3.1 案例 1:购物车总价计算
假设有一个购物车场景,需要根据商品列表动态计算总价:
const items = ref([
{ id: 1, price: 100, quantity: 2 },
{ id: 2, price: 50, quantity: 3 },
]);
const total = computed(() => {
return items.value.reduce((sum, item) => {
return sum + item.price * item.quantity;
}, 0);
});
当 items
中的任何一个商品数量或单价变化时,total
会自动更新。
3.2 案例 2:过滤与格式化数据
假设需要根据用户输入的关键词过滤列表:
const searchKeyword = ref('');
const filteredList = computed(() => {
return list.value.filter(item =>
item.name.includes(searchKeyword.value)
);
});
此场景中,filteredList
会根据 searchKeyword
的变化动态更新,无需手动触发。
四、进阶技巧与最佳实践
4.1 可写计算属性(Writable Computed)
通过返回一个包含 get
和 set
的对象,可以定义可修改的计算属性。例如,同步双向绑定的输入框值:
const fullName = computed({
get() {
return `${firstName.value} ${lastName.value}`;
},
set(newValue) {
const [first, last] = newValue.split(' ');
firstName.value = first;
lastName.value = last;
},
});
此时,模板中可以直接绑定 v-model="fullName"
,输入值会自动拆分到 firstName
和 lastName
。
4.2 优化性能:避免复杂计算
计算属性的函数应尽量简洁,避免嵌套循环或耗时操作。若需处理复杂逻辑,可将计算拆分为多个步骤或使用 watch
。
4.3 与 watch
的对比
特性 | vue3 computed | watch |
---|---|---|
执行时机 | 只在依赖变化时计算 | 可监听任意数据,执行自定义逻辑 |
返回值 | 返回计算后的值 | 无返回值,触发副作用 |
适用场景 | 需要直接使用的响应式值 | 需要执行异步操作或复杂逻辑 |
五、常见误区与解决方案
5.1 误区 1:计算属性未触发更新
若依赖的数据未被正确标记为响应式(如直接修改 reactive
对象的属性),计算属性可能不会更新。
解决方案:使用 Vue3 提供的响应式函数(如 ref
、reactive
)定义数据。
5.2 误区 2:在计算属性中执行副作用
计算属性的设计目的是返回值,而非执行副作用(如 API 请求)。
解决方案:改用 watch
或 watchEffect
处理副作用。
5.3 误区 3:过度依赖计算属性
若计算属性的依赖过多或嵌套过深,可能导致性能问题。
解决方案:拆分计算逻辑,或使用 markRaw
等工具优化。
六、总结与展望
vue3 computed 是 Vue3 响应式系统中的重要工具,它通过缓存和依赖追踪机制,帮助开发者高效管理组件状态。掌握其核心原理和最佳实践,能够显著提升代码的可维护性和性能。
未来,在 Vue4 或其他框架中,计算属性的概念可能会进一步优化,但其核心思想——“基于依赖的惰性计算”——仍将是响应式编程的核心。
通过本文,我们不仅学习了 vue3 computed 的语法和用法,还深入理解了其背后的响应式原理。希望读者能够将这些知识应用到实际项目中,写出更简洁、高效的 Vue3 代码。