computed 返回响应式只读值,依赖不变时自动缓存、只计算一次;支持 get/set 实现双向绑定,但 set 中须修改响应式源且避免循环依赖。

Computed 计算属性的核心用法很简单:它接收一个 getter 函数,返回一个响应式、自动缓存的只读值。只要依赖的响应式数据没变,无论访问多少次,都只执行一次计算。
基础写法:只读模式最常用
在 setup 中,用 computed() 包裹一个函数,该函数里读取 ref 或 reactive 的值即可:
- 必须 return 计算结果,否则模板中取不到值
- 函数内部只能读取响应式数据(ref.value、reactive.xxx),不能写非响应式变量或 Date.now() 这类无法追踪的值
- 返回的是一个带有 .value 的 ref-like 对象,模板中直接用 {{ fullName }},不用加 .value
示例:
const message = ref('Hello')
const reversedMessage = computed(() => message.value.split('').reverse().join(''))
依赖必须是响应式的,否则缓存不更新
Vue 只能追踪明确声明的响应式来源。常见错误包括:
- 解构 props 后直接使用:const { name } = props → name 是普通字符串,不响应;应改用 props.name 或配合 toRefs
- 用 arr[0] = 'new' 修改数组项 → Vue 3 Proxy 虽支持,但部分场景可能漏触发;稳妥做法是用 arr.splice(0, 1, 'new') 或替换整个数组
- 在 getter 里调用 Date.now() 或 Math.random() → 它们不在依赖图中,computed 永远不会重算
模板中多次使用,也只算一次
这是和 methods 的关键区别:
- 模板里写 5 次 {{ filteredList }},computed 只执行 getter 一次(首次访问时)
- methods 写成 {{ getFilteredList() }},每次渲染都会调用,哪怕依赖完全没变
- 尤其处理大数据过滤、格式化等耗时逻辑时,性能差距非常明显
可写 computed:少数需要双向同步的场景
如果确实需要赋值触发更新,可以传入一个对象,含 get 和 set:
const fullName = computed({
get() { return firstName.value + ' ' + lastName.value },
set(val) { const parts = val.split(' '); firstName.value = parts[0]; lastName.value = parts[1] || '' }
})
注意:set 中修改的必须是响应式源数据,且不能造成循环依赖(比如在 set 里又改 fullName 自己)。











