应优先使用 computed 替代模板中复杂表达式,以提升可读性、复用性与性能;需精准依赖响应式数据、避免副作用、不加括号调用、拆解复杂逻辑为多个小 computed。

直接在模板里写复杂表达式,比如 {{ items.filter(i => i.active).map(i => i.name).join(', ') }},看似方便,其实隐患不少:逻辑难读、无法复用、每次渲染都执行、还容易出错。用 computed 就能干净利落地解决这些问题。
把重复或耗时的计算逻辑抽出来
只要一段逻辑依赖响应式数据,且结果需要多次使用或计算成本较高,就该交给 computed。
- 比如购物车总价、筛选后的商品列表、用户权限状态等,都适合定义为计算属性
- 避免在模板中反复写
reduce、filter、sort这类操作 - 即使只是拼接几个字段,比如
{{ user.firstName + ' ' + user.lastName.toUpperCase() }},也建议封装成fullName计算属性,提升可读性和一致性
依赖要精准,别无意中扩大响应范围
computed 的缓存基于它实际访问的响应式数据。如果函数里引用了不该访问的 ref 或 reactive 字段,会导致本不该更新时也重新计算。
- 检查计算属性内部是否有多余的
this.xxx或state.xxx访问 - 避免在计算属性中调用非响应式方法(如
Date.now()、Math.random()),它们不会触发更新,但会让逻辑变得不可预测 - 数组过滤排序时,优先用
slice().sort()而不是直接修改原数组,确保不意外污染响应式源数据
模板中只用属性名,别加括号
computed 是属性,不是方法。写成 {{ filteredList() }} 就失去了缓存能力,退化成普通方法调用。
- 正确写法:
{{ filteredList }}(无括号) - 错误写法:
{{ filteredList() }}(有括号,每次渲染都执行) - 如果模板里看到带括号的“计算属性”,基本可以确定是误用,性能已受损
复杂逻辑拆解,用多个小 computed 组合
一个大而全的计算属性难以维护,也容易因某一小部分依赖变化导致整个重新计算。不如分层拆解。
- 例如搜索功能:先写
rawList(原始数据)、再写filteredByKeyword、最后写sortedAndLimited - 每一层只关心自己的依赖,变更影响范围小,调试也更清晰
- Vue 会自动按依赖关系调度执行顺序,无需手动控制



















