CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Vue 3 核心/课时/计算属性与侦听
RawBlame
课时目录12 节

Vue 3 核心

  1. 01Vue 是什么
  2. 02项目创建与 SFC
  3. 03模板语法
  4. 04响应式基础
  5. 05组件与 Props
  6. 06计算属性与侦听
  7. 07组合式 API 深入
  8. 08Vue Router
  9. 09Pinia 状态管理
  10. 10数据获取
  11. 11构建与部署
  12. 12综合练习

计算属性与侦听

computed、watch、watchEffect。

30 分钟

计算属性与侦听

这一课你将能做到

  1. 用 computed 派生显示值,并说明相对「方法每次重算」的缓存优势
  2. 用 watch / watchEffect 响应式地跑副作用(如同步 localStorage)
  3. 对照 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。

步骤 4:watch 多个源与旧值

watch(
  [filter, items],
  ([f, list], [prevF]) => {
    console.log("filter", prevF, "→", f, "len", list.length);
  },
  { deep: true }
);

对象/数组内容变需要 deep(或侦听更精确的 getter)。

步骤 5:watchEffect

import { watchEffect } from "vue";
watchEffect(() => {
  console.log("title now", title.value);
});

自动追踪 title;创建时立刻执行一次。适合简单同步;复杂异步更常用显式 watch。

步骤 6:对照 React

  • computed ≈ 依赖明确的 memo 派生
  • watch ≈ effect 里跟特定 state
    别在 computed 里发请求——两边都把「算值」和「干副作用」分开。

讲清楚要点

  1. computed 应纯:只根据依赖算值,不改别的状态、不请求网络。
  2. 可写 computed 少用;入门先掌握只读。
  3. watch 默认不深拷贝旧对象:比对引用;内容侦听要 deep 或精确路径。
  4. 清理:watch 可返回清理函数;异步竞态要取消。
  5. 先问:这是派生还是副作用? 选错 API 是结构味变臭的开始。
  6. 综合练习课会用 computed 做 Todo 过滤——本课先跑通。

你可能会懵的地方

  • computed 里改依赖?
    造成环与难懂更新;拆开。

  • watch 第一次不跑?
    默认懒;要立即跑加 { immediate: true }。

  • 和生命周期 onMounted?
    挂载一次的初始化放 onMounted;跟数据变的放 watch。

  • 性能焦虑?
    先正确,再分析;列表极大再考虑浅层或手工优化。

  • computed(() => props.x)?
    可以;或直接用 props。按需。

错法对照

错法问题正解
computed 里 fetch难取消、语义错watch / 事件里请求
模板塞超长过滤难测computed
watch 忘 deep 却期望内容变触发不回调deep 或换侦听方式
用 watch 硬算派生 UI 字符串多余状态computed
无清理的延迟请求竞态错显清理/序号守卫
把 filter 结果再存一份 ref 手同步双源真相只保留源 + computed

自测三问

  1. 何时用 computed 而不是 method?
  2. 为何不应在 computed 里写 localStorage?
  3. watch 与 watchEffect 怎么选?

小结一句话

computed 缓存派生值,watch 系处理副作用;先分清「算出来」还是「顺便做」。

官方延伸

  • 计算属性
  • 侦听器
  • 下一课:组合式 API 深入
加载本节练习…
← 上一课组件与 Props下一课 →组合式 API 深入