Vue3学习(4)- computed的使用
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>