前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Vue watchEffect 立即执行 computed 惰性 区别
VuVue侦听与生命周期

Vue watchEffect 为什么默认立即执行,而 computed 按需求值?

一份副作用需要开始工作,一份派生值则需要有人读取;两者的消费方式不同。

前端进阶之旅 · 一题精讲更新于 2026.09.06
Vue#侦听与生命周期#缓存
先看核心答案读代码示例
理解线索

比较初次工作由谁启动

  1. 效果创建默认立即执行函数,建立依赖并产生副作用
  2. 派生读取消费者读取 computed 时取得计算结果
  3. 依赖变化使相关结果需要重新评估,不等于无条件立即重算

计算次数可以用于实验观察,但不要在实际 computed 中用计数、请求等外部写入驱动业务。

核心回答

先记住这个答案

默认的 watchEffect 会在创建时执行效果函数,以产生初始副作用并建立实际读取的依赖;computed 返回可读取的派生引用,没有消费者读取时无需立即计算,读取时再按依赖状态求值并复用缓存。它们的差别来自用途:副作用负责做事,计算属性负责提供值。若 watchEffect 使用 post 调度,首次执行也会被推迟,不能把默认行为说成所有配置下都同步执行。

  • 默认 watchEffect 创建后开始执行
  • computed 为消费者提供按需求取的派生值
  • 缓存计算函数应保持纯粹

为什么要先执行才能知道依赖

watchEffect 的依赖来自函数实际运行时的同步读取,框架不能通过静态扫描猜测哪个条件分支会执行。第一次执行既让业务获得初始效果,也让响应式系统知道随后应订阅哪些数据变化。

computed 也需要运行 getter 才知道依赖,但它可以等到值被使用时再做这件事。例如一个折叠面板里的复杂统计从未被读取,就没有必要为了创建引用先完成全部计算。

通过读取位置观察求值行为

下例用计数变量观察 getter 是否运行,这是隔离实验的检测手段。创建 computed 后计数仍为零,第一次读取才计算;依赖未变化时再次读取复用结果,不会因为又访问一次 value 就完整重算。

同时创建的默认 watchEffect 会留下初始记录。示例把两个机制放在相同源上,只比较首次运行与读取关系,不把它们的执行次数当成实际项目里可依赖的性能承诺。

创建、读取与依赖变化TypeScript
import { ref, computed, watchEffect, nextTick } from 'vue'

const count = ref(2)
let getterRuns = 0
const doubled = computed(() => {
  getterRuns++ // 仅用于本次实验观察
  return count.value * 2
})
const createdRuns = getterRuns
const effects: number[] = []
const stop = watchEffect(() => { effects.push(count.value) })
const first = doubled.value
const second = doubled.value
const beforeChangeRuns = getterRuns
count.value = 3
await nextTick()
const beforeReadRuns = getterRuns
const latest = doubled.value
stop()

这个没有其他消费者的实验中,两次初始读取只计算一次,依赖改变后直到再次读取才得到六。效果记录则包含二和三;真实模板若正在读取 computed,本身就会成为推动求值的消费者。

职责决定哪种逻辑放在哪里

展示总价、筛选列表和拼接标签通常是由输入确定的派生值,放入 computed 可以避免额外维护同步状态。写本地存储、调用外部接口和控制第三方实例属于副作用,需要明确启动与清理流程。

不要把异步请求写进 computed 后期望框架等待它并管理失败。getter 返回 Promise 也只是一个计算结果,不会自动变成请求状态机;需要异步状态时,用明确的监听或事件流程管理数据与错误。

回答前,多想一步

容易答错的地方

认为依赖一变 computed 必然立刻重算
没有消费者读取的情况下,依赖变化可以先使结果需要重新评估,而不立即执行 getter。分析性能应结合谁读取了派生值及读取时机,不能只数源赋值次数。
在 computed 中做必须执行的工作
派生值可能没有被读取,也可能因消费者变化而在不同时间求值,因此不适合承担必须发生的请求、写入或日志流程。把必须执行的副作用放在明确的事件或侦听器中,并管理清理。
试着用自己的话回答

面试官还会怎么问?

为什么普通 watch 默认不会执行回调?

watch 可以先执行源 getter 建立观察并保存初值,而不立即运行副作用回调,二者本来就是分开的。需要初始业务执行时配置 immediate,这与 watchEffect 合并读取和副作用的模型不同。

watchPostEffect 创建时也同步执行吗?

不会按默认 pre 效果的首次同步方式执行。它使用 post 调度,初次效果也会延后到相应刷新阶段。面试回答需要先限定默认 watchEffect,避免将某种配置当成所有效果的共同保证。

getter 内只有 Date.now 为什么不会持续更新?

时间读取本身不是 Vue 响应式依赖,框架不会因为真实时间流逝自动使计算属性更新。若要持续展示时间,需要由定时更新的响应式源驱动,并在所有者结束时清理定时器。

从一道题,走向一组知识

把知识连起来

侦听与生命周期

Vue 什么时候用 watch,什么时候用 computed?

用途选择还要考虑异步、副作用和旧值比较的需求。

侦听与生命周期

Vue watch 的 flush post 和 watchPostEffect 如何在 DOM 更新后执行?

首次效果与 DOM 的相对时机还受 post 调度影响。

参考资料

  • Vue:计算属性与缓存
  • Vue:watchEffect 执行时机

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 为什么要先执行才能知道依赖
  3. 通过读取位置观察求值行为
  4. 职责决定哪种逻辑放在哪里
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑