1. 簡述與使用
作用:computed 用于基于響應式數據派生出新值,其值會自動緩存并在依賴變化時更新。
- ?緩存機制?:依賴未變化時直接返回緩存值,避免重復計算(通過 _dirty 標志位實現)。
- ?響應式更新?:依賴數據變更時觸發重新計算(通過 Vue 的 effect 依賴追蹤系統)。
如下圖片:
<template><div class="person">姓:<input type="text" v-model="firstName"> <br>名:<input type="text" v-model="lastName"> <br>全名:<span>{{fullName}}</span> <br><button @click="changeFullName">全名改為:li-si</button></div>
</template><script setup lang="ts" name="App">import {ref,computed} from 'vue'let firstName = ref('zhang')let lastName = ref('san')// 計算屬性——只讀取,不修改/* let fullName = computed(()=>{return firstName.value + '-' + lastName.value}) */// 計算屬性——既讀取又修改let fullName = computed({// 讀取get(){return firstName.value + '-' + lastName.value},// 修改set(val){console.log('有人修改了fullName',val)firstName.value = val.split('-')[0]lastName.value = val.split('-')[1]}})function changeFullName(){fullName.value = 'li-si'}
</script>
2. 與 methods 的區別
- 緩存?: computed 依賴不變時復用結果,methods 每次調用重新執行;
- 使用場景?:computed 純數據派生(如過濾、聚合),methods 事件處理或需主動觸發的邏輯;
- 模板調用?:computed 直接引用
(如 {{ value }})
,methods 需調用(如 {{ fn() }})
。
3. 使用方法詳解
3.1 ?基礎寫法(只讀)?
傳入 ?getter 函數,返回只讀的 Ref 對象:
<script setup>
import { ref, computed } from 'vue';
const count = ref(0);
const double = computed(() => count.value * 2); // 自動追蹤 count 依賴
</script>
適用場景?:模板中簡化復雜表達式(如數據格式化、條件判斷)。
3.2 完整寫法(可讀寫)
傳入包含 ?get/set 的對象,支持雙向綁定:
<template><div class="person">姓:<input type="text" v-model="firstName">名:<input type="text" v-model="lastName"><p>{{ fullName }}</p></div>
</template>
<script lang="ts">
export default {name: "Person"
}
</script><script setup lang="ts">
import {computed, ref} from "vue";const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed({// 寫法1// get: () => {// return firstName.value+" "+lastName.value// },get: () => `${firstName.value} ${lastName.value}`,set: (newValue) => {[firstName.value, lastName.value] = newValue.split(' ');}
});
// 修改 fullName 會觸發 set 方法
fullName.value = 'Jane Smith';
</script>
<style scoped lang=less>
</style>
適用場景?:v-model 綁定派生數據(如表單聯動)
3.3 傳遞參數
需在計算屬性內部返回函數?:
<template><div class="person"><div><div v-for="item in filterList(3)" :key="item">{{item}}</div></div></div>
</template>
<script lang="ts">
export default {name: "Person"
}
</script><script setup lang="ts">
import {computed, ref} from "vue";const list = ref([1, 2, 3]);
//值傳遞
const filterList = computed(()=> (max) => list.value.filter((item) => item < max));</script>
<style scoped lang=less>
</style>