计算属性与侦听
computed、watch、watchEffect。
30 分钟
计算属性与侦听
这一课你将能做到
- 用
computed派生显示值,并说明相对「方法每次重算」的缓存优势 - 用
watch/watchEffect响应式地跑副作用(如同步 localStorage) - 对照 React:
useMemo思想接近 computed;useEffect接近 watch 系
为什么要学
界面上很多东西是算出来的:过滤后的列表、全名、是否可提交。
把推导塞进模板会又长又难测;用 computed。需要「状态变了顺便做点事」时用 watch。
先建立图像
源状态 ref/reactive
├─ computed → 派生值(有缓存,依赖变才重算)
└─ watch/watchEffect → 副作用(请求、存盘、打日志)
| API | 产出 | 典型用途 |
|---|---|---|
| computed | 值 | 过滤列表、拼接文案 |
| watch | 副作用 | 侦听特定源 |
| watchEffect | 副作用 | 自动收集依赖立即跑 |
跟着做
步骤 1:computed 过滤
<script setup>
import { ref, computed } from "vue";
const filter = ref("all");
const items = ref([
{ id: 1, text: "学 SQL", done: true },
{ id: 2, text: "学 Vue", done: false },
]);
const visible = computed(() => {
if (filter.value === "done") return items.value.filter((t) => t.done);
if (filter.value === "active") return items.value.filter((t) => !t.done);
return items.value;
});
</script>
<template>
<button
v-for="f in ['all', 'active', 'done']"
:key="f"
type="button"
@click="filter = f"
>
{{ f }}
</button>
<ul>
<li v-for="t in visible" :key="t.id">{{ t.text }}</li>
</ul>
</template>
切换 filter,列表应变;visible 不要写成普通函数除非你清楚差别。
步骤 2:computed vs method
function visibleFn() {
return items.value.filter(/* … */);
}
模板里 visibleFn() 每次渲染都调用;visible computed 仅依赖变才重算。简单场景差异小,贵重计算用 computed。
步骤 3:watch 存盘
<script setup>
import { ref, watch } from "vue";
const title = ref(localStorage.getItem("demo-title") || "");
watch(title, (v) => {
localStorage.setItem("demo-title", v);
});
</script>
<template>
<input v-model="title" />
</template>
刷新后输入框应恢复。这是副作用,不该塞进 computed。