vue3的computed是处理响应式数据二次加工最自然高效的方式,它自动追踪依赖、仅在依赖变化时重新计算、结果可直接用于模板且不破坏单向数据流。

Vue3 的 computed 是处理响应式数据二次加工最自然、高效的方式——它自动追踪依赖、只在必要时重新计算、结果可直接用于模板,且不破坏单向数据流。
一、基础写法:用 computed 包裹逻辑函数
在 setup() 中,通过 import { computed } from 'vue' 引入,传入一个返回值的函数即可:
- 函数内访问的响应式变量(如
ref或reactive属性)会被自动追踪 - 返回值会封装成一个带有
.value的响应式引用对象 - 首次读取
.value时才执行函数;后续读取若依赖未变,则直接返回缓存结果
示例:
import { ref, computed } from 'vue'
export default {
setup() {
const firstName = ref('Alice')
const lastName = ref('Smith')
const fullName = computed(() => {
console.log('正在计算 fullName') // 仅首次或依赖变化时打印
return `${firstName.value} ${lastName.value}`
})
return { firstName, lastName, fullName }
}
}
模板中使用:{{ fullName }}(无需 .value,模板中自动解包)
二、处理 props:安全地派生子组件状态
父组件传入 props 后,子组件不应直接修改,也不应在模板里反复写表达式。用 computed 封装是最推荐做法:
- 依赖 props 的值,一旦 props 更新,计算属性自动重算
- 避免了
data的静态快照问题,也规避了methods每次渲染都执行的开销 - 适合做格式化(如日期、金额)、过滤(如 status === 'active')、组合(如拼接 title + suffix)等
示例(子组件):
export default {
props: ['rawTitle', 'level'],
setup(props) {
const displayTitle = computed(() => {
const prefix = props.level === 1 ? '【重要】' : '→'
return `${prefix}${props.rawTitle || '无标题'}`
})
return { displayTitle }
}
}
三、进阶要点:只读 vs 可写、避免副作用
computed 默认是只读的(即只有 getter)。如需支持赋值(比如双向绑定场景),需显式提供 get 和 set:
const password = ref('')
const maskedPassword = computed({
get() {
return password.value.replace(/./g, '*')
},
set(val) {
password.value = val.trim()
}
})
注意两个常见坑:
-
不要在 computed 函数里执行副作用(如发请求、改 DOM、调用
console.log以外的外部状态),因为它可能被缓存,导致副作用不触发或多次触发 -
确保所有依赖都是响应式的:如果用了普通变量、
const字面量或非响应式对象属性,computed 不会更新
四、为什么它比 methods 更合适?
对比模板中调用方法:{{ formatName() }}
-
methods每次组件重新渲染都会执行,哪怕参数没变 -
computed基于依赖缓存,只要firstName和lastName不变,fullName就不会重复拼接 - 尤其在 v-for 列表、频繁触发的事件中,缓存带来的性能差异明显
简单说:要展示派生值 → 用 computed;要响应用户动作 → 用 methods。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











