前端进阶之旅前端进阶之旅
  • 基础篇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 effectScope 创建 stop 批量停止 副作用
VuVue侦听与生命周期

Vue effectScope 是什么,如何一次停止其中的所有副作用?

当一项功能内部创建很多响应式效果时,作用域可以把“谁负责结束它们”变成一个明确对象。

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

作用域把创建与销毁绑在一起

  1. 创建容器effectScope 返回可运行、可停止的所有者对象
  2. 同步收集run 中创建的响应式效果登记到当前作用域
  3. 集中结束stop 停止效果并执行作用域内登记的清理

作用域不是通用资源管理器,外部资源仍要通过清理函数接入它的结束流程。

核心回答

先记住这个答案

effectScope 会建立一个响应式效果作用域;在 scope.run 的同步执行期间创建的 computed、watch 和 watchEffect 等效果会被它收集,调用 scope.stop 后可以一起停止。它适合组合式函数、临时工作区或独立响应式模块的集中销毁。作用域只管理被收集的响应式效果和登记的清理,并不会自动关闭未登记的定时器、连接或普通异步任务。作用域停止后再次 run 会返回 undefined,不能用它复活旧作用域。

  • run 的同步执行期负责收集效果
  • stop 统一结束已收集效果与清理
  • 停止后的作用域不能重新启用

收集的是创建动作而非任意引用

一个 watch 在 scope.run 之外已经创建完成,后来即使把停止句柄放进作用域变量,也不会因此自动归属该作用域。关键是响应式效果创建时,哪个作用域处于活动状态。

同样地,run 回调里安排一个定时器,定时器稍后才创建 watch,这个创建动作已经越过同步收集窗口。需要延迟创建时应重新设计所有权,或者在正确的活动作用域中显式执行并保存停止路径。

用一次 stop 结束一组观察

下例在一个作用域中创建 watchEffect 和 watch。源变化后两者都留下记录,停止作用域再修改源,记录不再增长。调用方只需要保管 scope,无需逐个暴露内部句柄。

computed 也可以被作用域收集,但它仍保持按需取值的语义。作用域回答的是生命周期归属,不能把派生值的惰性计算、监听调度和新旧值模型合并成同一个概念。

集中管理两个响应式效果TypeScript
import { effectScope, ref, watch, watchEffect } from 'vue'

const count = ref(0)
const events: string[] = []
const scope = effectScope()
scope.run(() => {
  watchEffect(() => { events.push('effect:' + count.value) })
  watch(count, value => { events.push('watch:' + value) })
})

将 count 改为一并等待更新后,记录包含初次 effect 以及两种观察的一次更新。调用 scope.stop,再改为二并等待,记录保持不变;这验证的是统一停止,不承诺两个回调之间的所有内部排序。

停止以后要新建作用域

scope.stop 表示这批效果的所有权已经结束。需要重新开始时,应创建新的 effectScope 并重新执行初始化函数,而不是在旧 scope 上再次 run 或假定旧 computed 会重新订阅。

可重启模块应把创建过程封装为 start,把当前作用域保存在单一位置;再次 start 前先 stop 旧作用域,并清楚重置哪些业务状态。是否保留上次数据与作用域是否仍活跃是两个独立决定。

回答前,多想一步

容易答错的地方

认为 run 中所有异步后续都会被收集
run 只在同步执行回调时提供当前作用域。Promise 或定时器恢复后才创建的响应式效果需要自己的所有权安排,不能由代码缩进位置推断它仍属于原 scope。
只停止 watcher 不清理外部资源
观察回调创建的订阅、连接或定时器若没有登记清理,停止响应式效果也无法知道怎样关闭它们。资源建立时就用 onCleanup 或 onScopeDispose 接入结束流程。
试着用自己的话回答

面试官还会怎么问?

scope.run 的返回值有什么用途?

活动作用域会返回回调自己的结果,可用于把作用域内创建的状态和操作暴露给调用方。作用域已经停止时 run 返回 undefined,因此调用者不能无条件断言初始化结果存在。

组件 setup 中还需要手动创建 effectScope 吗?

组件本身已经为同步创建的响应式效果提供作用域,普通组件逻辑通常无需再包一层。需要把一组效果提前重置、独立于局部流程集中管理时,显式作用域才更有价值。

如何验证没有漏掉异步创建的监听?

记录每份效果的创建、停止和回调次数,在 stop 后继续修改所有测试源。再让延迟创建发生在 stop 之后,确认代码会拒绝创建或把新效果交给另一个明确所有者。

从一道题,走向一组知识

把知识连起来

侦听与生命周期

Vue 嵌套 effectScope 在父级停止时会怎样?

作用域嵌套后,父级停止会继续处理默认归属的子作用域。

侦听与生命周期

Vue onScopeDispose 在什么时机执行,适合清理哪些资源?

非响应式资源可以通过作用域清理回调接入统一结束流程。

侦听与生命周期

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

作用域归属不会改变 computed 的按需取值和 watchEffect 的运行模型。

参考资料

  • Vue:effectScope API
  • Vue RFC:响应式效果作用域

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

本题目录
  1. 先记住这个答案
  2. 收集的是创建动作而非任意引用
  3. 用一次 stop 结束一组观察
  4. 停止以后要新建作用域
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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