Vue 计算属性
Vue 计算属性
基础示例
模板中的表达式虽然方便,但仅适用于简单操作。若在模板中写入过多逻辑,会导致模板臃肿、难以维护。例如,有一个包含嵌套数组的对象:
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
若要根据 author 是否有书籍展示不同信息,直接在模板中编写逻辑如下:
<p>Has published books:</p>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
这种写法不仅可读性差,还存在重复代码的问题(若多次使用该逻辑)。因此,推荐使用计算属性描述依赖响应式状态的复杂逻辑,重构后的示例如下:
<script setup>
import { reactive, computed } from 'vue'
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
</script>
<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</template>

核心说明
computed()方法接收一个 getter 函数,返回值为计算属性 ref。- 可通过
publishedBooksMessage.value访问计算结果(与普通 ref 一致)。 - 模板中会自动解包计算属性 ref,无需添加
.value。 - Vue 会自动追踪响应式依赖:当
author.books变化时,所有依赖publishedBooksMessage的绑定都会同步更新。
计算属性缓存 vs 方法
功能对比
通过函数调用也能实现与计算属性相同的结果,例如:
<!-- 模板 -->
<p>{{ calculateBooksMessage() }}</p>
// 组件中
function calculateBooksMessage() {
return author.books.length > 0 ? 'Yes' : 'No'
}
但两者的核心区别在于缓存机制:
| 特性 | 计算属性 | 方法 |
|---|---|---|
| 缓存机制 | 基于响应式依赖缓存结果 | 无缓存,每次调用重新执行 |
| 执行时机 | 仅依赖更新时重新计算 | 组件重渲染时必执行 |
| 性能优化 | 适合复杂计算/频繁访问场景 | 适合无需缓存的简单逻辑 |
关键示例
- 计算属性的缓存特性:
// Date.now() 非响应式依赖,因此该计算属性永远不会更新
const now = computed(() => Date.now())
- 缓存的意义:
- 若有一个耗性能的计算属性(如循环巨大数组),且被多次引用,缓存可避免重复执行 getter 函数,大幅提升性能。
- 若确定无需缓存,直接使用方法调用即可。
可写计算属性
计算属性默认只读,修改时会触发运行时警告。如需“可写”功能,可同时提供 getter 和 setter:
<script setup>
import { ref, computed } from 'vue'
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
// getter:获取计算结果
get() {
return firstName.value + ' ' + lastName.value
},
// setter:修改时触发的逻辑
set(newValue) {
// 解构赋值拆分新值
[firstName.value, lastName.value] = newValue.split(' ')
}
})
</script>
使用场景
当修改计算属性时,会触发 setter 并同步更新依赖的响应式状态:
// 执行后,firstName 变为 'Jane',lastName 变为 'Smith'
fullName.value = 'Jane Smith'
获取上一个值
- 仅支持 Vue 3.4+
- 可通过计算属性 getter 的第一个参数,获取上一次的计算结果。
只读计算属性示例
<script setup>
import { ref, computed } from 'vue'
const count = ref(2)
// 逻辑:count ≤ 3 时返回当前值;count ≥ 4 时返回最后一个满足条件的值(直到 count 再次 ≤ 3)
const alwaysSmall = computed((previous) => {
if (count.value <= 3) {
return count.value
}
return previous // 返回上一个值
})
</script>
可写计算属性示例
<script setup>
import { ref, computed } from 'vue'
const count = ref(2)
const alwaysSmall = computed({
get(previous) {
if (count.value <= 3) {
return count.value
}
return previous
},
set(newValue) {
count.value = newValue * 2 // 修改时同步更新 count
}
})
</script>

浙公网安备 33010602011771号