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 }},它会根据 firstNamelastName 的变化自动更新。


二、响应式原理与内部机制

2.1 依赖追踪机制

vue3 computed 的核心是响应式系统。当计算属性函数被调用时,Vue3 会自动追踪其内部访问的响应式数据(如 refreactive 对象的属性)。这些数据被称为“依赖”。

图解流程:

  1. fullName 被首次访问时,其内部会读取 firstNamelastName 的值。
  2. Vue3 将这两个值标记为 fullName 的依赖。
  3. firstNamelastName 发生变化,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)

通过返回一个包含 getset 的对象,可以定义可修改的计算属性。例如,同步双向绑定的输入框值:

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",输入值会自动拆分到 firstNamelastName

4.2 优化性能:避免复杂计算

计算属性的函数应尽量简洁,避免嵌套循环或耗时操作。若需处理复杂逻辑,可将计算拆分为多个步骤或使用 watch

4.3 与 watch 的对比

特性vue3 computedwatch
执行时机只在依赖变化时计算可监听任意数据,执行自定义逻辑
返回值返回计算后的值无返回值,触发副作用
适用场景需要直接使用的响应式值需要执行异步操作或复杂逻辑

五、常见误区与解决方案

5.1 误区 1:计算属性未触发更新

若依赖的数据未被正确标记为响应式(如直接修改 reactive 对象的属性),计算属性可能不会更新。
解决方案:使用 Vue3 提供的响应式函数(如 refreactive)定义数据。

5.2 误区 2:在计算属性中执行副作用

计算属性的设计目的是返回值,而非执行副作用(如 API 请求)。
解决方案:改用 watchwatchEffect 处理副作用。

5.3 误区 3:过度依赖计算属性

若计算属性的依赖过多或嵌套过深,可能导致性能问题。
解决方案:拆分计算逻辑,或使用 markRaw 等工具优化。


六、总结与展望

vue3 computed 是 Vue3 响应式系统中的重要工具,它通过缓存和依赖追踪机制,帮助开发者高效管理组件状态。掌握其核心原理和最佳实践,能够显著提升代码的可维护性和性能。

未来,在 Vue4 或其他框架中,计算属性的概念可能会进一步优化,但其核心思想——“基于依赖的惰性计算”——仍将是响应式编程的核心。


通过本文,我们不仅学习了 vue3 computed 的语法和用法,还深入理解了其背后的响应式原理。希望读者能够将这些知识应用到实际项目中,写出更简洁、高效的 Vue3 代码。

最新发布