computed
在 Vue 3 的 Composition API 中,computed
用于定義響應式計算屬性
它的核心特性是自動追蹤依賴、緩存計算結果(依賴未變化時不會重新計算)
基本用法
1. 定義只讀計算屬性
import { ref, computed } from 'vue';const count = ref(0);
const doubleCount = computed(() => count.value * 2); // 返回一個 Ref 對象console.log(doubleCount.value); // 0 → 初始值
count.value = 2;
console.log(doubleCount.value); // 4 → 自動更新
2. 在模板中使用
<template><div>{{ doubleCount }}</div> <!-- 自動解包,無需 .value -->
</template>
computed
的響應式依賴
- 自動追蹤依賴:計算屬性會追蹤其內部使用的所有響應式變量(如
ref
或reactive
)。 - 緩存機制:只有依賴變化時才會重新計算,否則直接返回緩存值。
const a = ref(1);
const b = ref(2);
const sum = computed(() => a.value + b.value);a.value = 3; // sum 自動重新計算 → 3 + 2 = 5
b.value = 4; // sum 再次計算 → 3 + 4 = 7
可寫計算屬性(Setter)
computed
可以接受一個包含 get
和 set
的對象,實現雙向綁定:
const firstName = ref('John');
const lastName = ref('Doe');// 可寫計算屬性
const fullName = computed({get: () => `${firstName.value} ${lastName.value}`,set: (newValue) => {const [first, last] = newValue.split(' ');firstName.value = first;lastName.value = last;},
});// 修改計算屬性
fullName.value = 'Jane Smith'; // 自動更新 firstName 和 lastName
console.log(firstName.value); // 'Jane'
console.log(lastName.value); // 'Smith'
與 reactive
結合使用
將計算屬性綁定到 reactive
對象中:
import { reactive, computed } from 'vue';const state = reactive({price: 100,quantity: 2,
});// 計算總價
state.total = computed(() => state.price * state.quantity);console.log(state.total.value); // 200
性能優化:避免重復計算
計算屬性會緩存結果,以下場景體現優勢:
const list = ref([1, 2, 3, 4, 5]);// 計算過濾后的列表(只有 list 變化時重新計算)
const evenNumbers = computed(() => list.value.filter(num => num % 2 === 0));list.value.push(6); // evenNumbers 自動更新為 [2,4,6]
注意事項
-
避免副作用:計算屬性應是純函數,不要在其中修改外部狀態。
// ? 錯誤示例(副作用) const invalidComputed = computed(() => {count.value++; // 禁止修改依賴!return count.value; });
-
依賴非響應式數據:如果依賴非響應式變量,計算屬性不會更新:
let staticValue = 10; const badComputed = computed(() => staticValue); // 不會更新!
-
性能敏感場景:復雜計算建議使用
computed
緩存結果,而非在模板中直接調用方法。
與 Vue 2 的對比
特性 | Vue 2 的 computed | Vue 3 的 computed |
---|---|---|
定義位置 | computed 選項 | 在 setup 中通過函數定義 |
返回值類型 | 直接通過屬性訪問 | Ref 對象(需 .value 訪問) |
響應式依賴追蹤 | 自動 | 自動 |
可寫性 | 不支持 Setter | 支持 Setter |
完整示例
<template><div><input v-model="price" type="number" placeholder="價格"><input v-model="quantity" type="number" placeholder="數量"><p>總價: {{ total }}</p><button @click="resetTotal">重置總價</button></div>
</template><script setup>
import { ref, computed } from 'vue';const price = ref(0);
const quantity = ref(0);// 計算總價
const total = computed({get: () => price.value * quantity.value,set: (value) => {price.value = value / 2;quantity.value = 2;},
});// 通過 Setter 修改計算屬性
const resetTotal = () => {total.value = 0; // 觸發 Setter → price=0, quantity=0
};
</script>