深入解析 Vue 3 中的 `computed` 以及相关知识点

server/2024/11/20 2:00:35/
webkit-tap-highlight-color: rgba(0, 0, 0, 0);">

深入解析 Vue 3 中的 computed 以及相关知识点

一、引言

在 Vue.js 中,computed 属性用于定义计算属性,是一个基于响应式依赖的缓存值,只有当依赖的数据变化时才会重新计算。它是构建高效、性能优异的 Vue 应用的重要工具。

Vue 3 通过 Composition API 为 computed 提供了更灵活的用法和更强的可扩展性。本文将深入讲解 Vue 3 中 computed 的用法及其相关知识点,并提供基于 语法糖 的完整示例,帮助你快速掌握。


二、computed 的基础用法

在 Vue 3 中,computed 是通过 @vue/reactivity 提供的一个函数,用于创建响应式的计算属性。

1. 定义只读计算属性

示例代码

<script setup>
import { ref, computed } from 'vue'// 定义响应式数据
const firstName = ref('张')
const lastName = ref('三')// 定义计算属性
const fullName = computed(() => `${firstName.value} ${lastName.value}`)
</script><template><div><p>名字:{{ fullName }}</p><input v-model="firstName" placeholder="姓氏" /><input v-model="lastName" placeholder="名字" /></div>
</template>

输出说明

  • fullName 是一个基于 firstNamelastName 计算得出的值。
  • firstNamelastName 更新时,fullName 会自动重新计算并更新到视图中。

2. 定义可写计算属性

在某些情况下,我们需要允许计算属性被写入。可以通过 getset 配合实现。

示例代码

<script setup>
import { ref, computed } from 'vue'const firstName = ref('张')
const lastName = ref('三')// 定义可读写的计算属性
const fullName = computed({get: () => `${firstName.value} ${lastName.value}`,set: (value) => {const [first, last] = value.split(' ')firstName.value = first || ''lastName.value = last || ''}
})
</script><template><div><p>名字:{{ fullName }}</p><input v-model="fullName" placeholder="全名" /></div>
</template>

输出说明

  • fullName 支持双向绑定:可以从输入框中更新 firstNamelastName 的值。

三、computedwatch 的对比

1. 功能上的区别
特性computedwatch
用途依赖值变化时,自动返回计算后的新值监控一个或多个响应式数据的变化,并执行回调函数
是否有返回值有,始终返回计算结果无,回调函数不返回值
是否缓存是,只有依赖发生变化时才会重新计算否,每次依赖值变化时都会执行回调
2. 选择何时使用
  • 使用 computed:当需要基于一个或多个数据源计算新值,并在模板中直接使用时。
  • 使用 watch:当需要执行副作用操作(如调用 API、写日志等)时。

四、computed 的高级用法

1. 依赖多重数据

计算属性可以依赖多个响应式数据,并自动跟踪这些依赖。

示例代码

<script setup>
import { ref, computed } from 'vue'const items = ref([{ name: '苹果', price: 3 },{ name: '香蕉', price: 2 },{ name: '橙子', price: 4 }
])// 计算总价格
const totalPrice = computed(() => items.value.reduce((sum, item) => sum + item.price, 0))
</script><template><div><ul><li v-for="item in items" :key="item.name">{{ item.name }}: {{ item.price }} 元</li></ul><p>总价:{{ totalPrice }} 元</p></div>
</template>

说明

  • totalPrice 会根据 items 的变化自动更新。
  • 在 Vue 中,你不需要手动声明依赖关系,computed 会自动追踪依赖。

2. 配合 watchEffect 使用

有时需要在计算属性中依赖外部副作用的场景,可以配合 watchEffect 使用(副作用是指任何会影响外部状态的行为,比如打印日志,发起网络请求,操作DOM,调用外部API)。

示例代码

<script setup>
import { ref, computed, watchEffect } from 'vue'const basePrice = ref(100)
const discount = ref(10)const finalPrice = computed(() => basePrice.value - discount.value)// 打印计算过程
watchEffect(() => {console.log(`基础价格: ${basePrice.value}, 折扣: ${discount.value}, 最终价格: ${finalPrice.value}`)
})
</script><template><div><p>最终价格:{{ finalPrice }}</p><input v-model.number="basePrice" type="number" placeholder="基础价格" /><input v-model.number="discount" type="number" placeholder="折扣" /></div>
</template>

五、computed 的原理解析

Vue 3 中的 computed 是基于响应式系统实现的,其原理大致如下:

  1. 依赖收集:在 computedgetter 函数中访问响应式数据时,会自动注册对这些数据的依赖。
  2. 懒惰计算computed 默认采用 惰性求值 策略,只有当计算属性被访问时,才会重新计算。
  3. 缓存机制computed 会缓存计算结果,只有在依赖值发生变化时,才会重新计算。

核心源码(简化版):

javascript">function computed(getter) {let cachedValuelet dirty = trueconst effect = new ReactiveEffect(getter, () => {dirty = true})return {get value() {if (dirty) {cachedValue = effect.run()dirty = false}return cachedValue}}
}

六、常见问题与优化

1. 不要在 computed 中执行副作用

错误示例

javascript">const invalid = computed(() => {console.log('执行副作用') // 不推荐return someValue
})

优化建议

  • 将副作用逻辑放在 watchwatchEffect 中。
2. 避免复杂计算

计算属性过于复杂可能导致性能问题。建议将复杂逻辑拆分成多个小的 computed 属性。


七、总结

  • computed 是 Vue 3 中高效管理依赖关系的重要工具,通过缓存和懒加载提高性能。
  • 它适合处理基于响应式数据的派生状态,并提供只读和可写两种模式。
  • watch 相比,computed 更适合用于模板中的派生值计算,而 watch 更适合处理副作用。

http://www.ppmy.cn/server/143348.html

相关文章

GIT将源码推送新分支

1. 创建并切换到新分支 首先&#xff0c;确保你在本地创建了一个新的分支并切换到该分支&#xff1a; git checkout -b new-branch-namenew-branch-name 是你要创建的新分支名称&#xff0c;替换为你需要的名称即可。 2. 确保所有更改已提交 在推送之前&#xff0c;确保你的…

全志科技嵌入式面试题及参考答案

C 语言的编译过程是怎样的? C 语言的编译过程主要包括以下几个阶段。 首先是预处理阶段。在这个阶段,预处理器会处理以 “#” 开头的预处理指令。比如 #include 指令会把指定的头文件内容插入到当前的源文件中,这使得我们可以在程序中使用标准库函数或者自定义头文件中的声明…

国产RestApi工具Apifox使用介绍

常见RestApi工具介绍 常见的接口工具有Postman、Swagger等&#xff0c;当然还有其他很多种&#xff0c;就不列举了&#xff0c;在遇到Apifox之前&#xff0c;我一直都使用的Postman&#xff0c;但是Postman有个弊端&#xff0c;就是网络问题&#xff0c;还有就是免费有限制&…

Ubuntu24.04上安装和配置MariaDB

Ubuntu24.04上安装和配置MariaDB #切换到root用户 sudo su -#更新系统&#xff0c;确保所有的软件都是最新的 apt update && sudo apt upgrade -y#要添加 MariaDB 存储库&#xff0c;我们需要安装一个名为 software-properties-common 的包 apt install software-prop…

【前端】技术演进发展简史

一、前端 1、概述 1990 年&#xff0c;第一个web浏览器诞生&#xff0c;Tim 以超文本语言 HTML 为基础在 NeXT 电脑上发明了最原始的 Web 浏览器。 1991 年&#xff0c;WWW诞生&#xff0c;这标志着前端技术的开始。 前端&#xff08;Front-end&#xff09;和后端&#xff08;…

WebRTC实现双端音视频聊天(Vue3 + SpringBoot)

目录 概述 相关概念 双端连接整体实现步骤概述 文章代码实现注意点 STUN和TURN服务器的搭建 开发过程描述 后端开发流程 前端开发流程 效果演示 Gitee源码地址 概述 文章描述使用WebRTC技术实现一对一音视频通话。 由于设备摄像头限制&#xff08;一台电脑作测试无法…

攻防世界-web php_rce[wp]

进入环境 发现是thinkphp框架&#xff0c;使用thinkphp框架工具进行检测 发现存在Thinkphp5.0.22/5.1.29RCE 工具生成一个一句话木马 蚁剑连接

计算机组成原理笔记----基础篇

计算机系统硬件软件 软件 ├── 系统软件 │ ├── 操作系统 │ └── 工具软件 └── 应用软件├── 办公软件├── 媒体软件└── 浏览器软件硬件 ├── 计算机硬件 │ ├── 中央处理器&#xff08;CPU&#xff09; │ ├── 存储设备 │ │ ├── …