计算属性是 Vue 3 核心特性之一,专门用于声明式依赖计算,基于响应式依赖自动缓存计算结果,仅在依赖数据发生变化时才会重新计算,从根本上避免了重复计算带来的性能损耗。 在组合式 API 中,我们通过 computed 函数声明计算属性,默认提供只读能力,也可通过配置 getter 和 setter 实现可写计算属性;当依赖的响应式数据更新时,计算属性会自动重新计算,视图也会同步刷新。
基本计算属性为只读模式,仅需传入一个 getter 函数,返回计算结果即可,是开发中最常用的形式。
<template>
<div>
<!-- 计算属性直接使用,无需调用 -->
<span>求和结果:{{ sum }}</span>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
// 定义响应式依赖数据
const num1 = ref<number>(1)
const num2 = ref<number>(2)
// 定义只读计算属性
// 自动缓存:仅 num1/num2 变化时重新计算
const sum = computed((): number => {
console.log('执行计算')
return num1.value + num2.value
})
</script>
<style scoped>
</style>响应式依赖 使用 ref 声明基础响应式数据 num1 和 num2,作为计算属性的依赖源。
计算属性定义 调用 computed() 传入 getter 函数,返回依赖数据的计算结果,函数返回值会自动推导类型。
缓存机制(核心特性) 计算属性会缓存计算结果,无论模板中调用多少次,只要依赖数据不变,都不会重复执行 getter 函数。
视图自动更新 当 num1 或 num2 发生修改时,计算属性自动重新计算,模板中的值同步更新。
计算属性默认只读,直接修改会触发运行时警告。针对特殊业务场景,Vue 3 支持通过同时配置 getter 和 setter,创建可写计算属性,实现双向绑定逻辑。
<template>
<div>
<input v-model="firstName" placeholder="姓氏">
<input v-model="lastName" placeholder="名字">
<!-- 计算属性支持 v-model 双向绑定 -->
<input v-model="fullName" placeholder="全名">
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
// 基础响应式数据
const firstName = ref<string>('John')
const lastName = ref<string>('Doe')
// 定义可写计算属性
const fullName = computed({
// getter:获取值(拼接全名)
get(): string {
return `${firstName.value} ${lastName.value}`
},
// setter:设置值(拆分全名并更新源数据)
set(newValue: string): void {
// 解构赋值,拆分字符串
[firstName.value, lastName.value] = newValue.split(' ')
}
})
</script>
<style scoped>
</style>语法结构 传入一个包含 get 和 set 方法的对象,替代单纯的 getter 函数。
getter 方法 读取计算属性时触发,负责拼接 / 计算并返回结果。
setter 方法 主动修改计算属性时触发,接收新值作为参数,可反向更新依赖的原始响应式数据。
双向绑定 可写计算属性直接支持 v-model,是表单复杂逻辑绑定的最佳方案。
联动更新 修改 firstName/lastName 会更新 fullName;修改 fullName 也会反向更新原始数据。
依赖追踪 计算属性会自动追踪内部使用的响应式数据,无需手动声明依赖。
惰性计算 只有在依赖数据变化时,才会重新执行计算逻辑。
缓存优先 相比方法(methods),计算属性的缓存机制性能更高,适合复用计算逻辑。
优先使用计算属性处理模板中的复杂逻辑,保持模板简洁。
无修改需求时,使用只读计算属性;需要双向绑定时,使用可写计算属性。
计算属性中只做纯计算,不执行异步请求、DOM 操作等副作用逻辑。
配合 TypeScript 使用,自动推导类型,提升代码健壮性。