Vue的computed用于基于响应式数据自动派生缓存值,如购物车总价、数量、是否可结算等;相比methods,它仅在依赖变化时重新计算,性能更优且逻辑清晰。

Vue 的 computed 计算属性,核心是用来基于响应式数据自动派生新值,且自带缓存——只要依赖的数据没变,多次访问不会重复执行函数。购物车总价、商品数量、是否可结算等,都是它的典型用武之地。
一、为什么购物车必须用 computed 而不是 methods?
如果用 methods 写一个 getCartTotal(),每次模板里调用(比如 {{ getCartTotal() }}),它会在每次组件重新渲染时都执行一次,哪怕购物车商品数组根本没变;而 computed 会监听 cartItems 的变化,仅当其中某个商品的 price 或 count 改了,才重新计算,性能更好、逻辑更清晰。
二、基础写法:单个总价汇总
假设你的购物车数据长这样:
data() {return {
cartItems: [
{ id: 1, name: 'iPhone', price: 5999, count: 2 },
{ id: 2, name: 'AirPods', price: 1299, count: 1 }
]
}
}
在 computed 中定义总价:
立即学习“前端免费学习笔记(深入)”;
computed: {totalPrice() {
return this.cartItems.reduce((sum, item) => {
return sum + item.price * item.count;
}, 0);
}
}
模板中直接使用:{{ totalPrice }} —— 页面会实时更新,无需手动触发。
三、进阶组合:数量、空状态、禁用结算
一个真实购物车还需要更多联动逻辑,全部用 computed 拆解更清晰:
-
商品总数:
totalCount() { return this.cartItems.reduce((n, item) => n + item.count, 0); } -
是否为空:
isEmpty() { return this.cartItems.length === 0; } -
是否可结算:
canCheckout() { return !this.isEmpty && this.totalPrice > 0; }(注意:这里直接复用了上面的totalPrice,computed 可相互引用) -
格式化价格(带¥和小数):
formattedTotal() { return `¥${this.totalPrice.toFixed(2)}`; }
这些属性在模板中可自由使用:v-if="!isEmpty"、:disabled="!canCheckout"、{{ formattedTotal }}……逻辑内聚,一目了然。
四、注意事项:别在 computed 里做副作用
computed 函数必须是纯函数:只读取响应式数据,返回新值,不修改原数据、不发请求、不操作 DOM。比如下面这些是错的:
- 在 totalPrice 里调用
this.$http.post(...) - 执行
this.cartItems.push(...) - 调用
document.title = ...
需要副作用?请用 watch 监听 cartItems 变化,或在用户点击按钮时用 methods 处理。


















