vscode的onfocuschange模式仅保存当前激活的已命名非只读文件,并非保存所有已修改文件;它在编辑器控件失焦时触发,受工作区设置、文件状态及系统焦点事件稳定性影响。

VSCode 没法“失去焦点时自动保存所有已修改文件”——它只保存当前激活的、已命名、非只读的文件,这是硬限制,不是配置能绕过的。
onFocusChange 是你要找的模式,但它不等于“所有文件”
你真正需要的行为(切到浏览器/终端就保存当前正在编辑的内容),靠的是 files.autoSave 设为 "onFocusChange"。它触发条件是:当前编辑器控件失焦,比如你从 index.ts 标签页点进终端、搜索框、甚至 Alt+Tab 切到 Chrome,都会保存那个 index.ts。
- 只保存当前激活的文件,其他已修改但未打开的 tab 不会动
- 未命名文件(
Untitled-1)直接跳过,不报错也不提示 - 只读文件(权限受限或被其他进程占用)同样静默忽略
- 如果启用了
editor.formatOnSave,而 Prettier 等插件格式化失败,VSCode 会回滚本次保存——你看到的“没保存”,其实是保存后又被撤回了
工作区设置会覆盖用户设置,检查 .vscode/settings.json
即使你在用户设置里选了 "onFocusChange",只要项目根目录下有 .vscode/settings.json,且里面写了 "files.autoSave": "off" 或 "files.autoSave": "afterDelay",它就会生效,用户级设置完全无效。
- 打开命令面板(
Ctrl+Shift+P),运行Preferences: Open Workspace Settings (JSON),确认没有冲突配置 - 如果想统一管理,可在工作区设置中显式写
"files.autoSave": "onFocusChange",避免依赖用户设置 - 大小写敏感:
"onfocuschange"或"on-focus-change"都不识别,必须是"onFocusChange"
onWindowChange 看似更“全”,实际更不可靠
有人以为 "onWindowChange" 才是“切出 VSCode 就保存”,但它监听的是整个窗口系统焦点,触发条件极窄:
- macOS 最小化窗口不触发;Windows 下被全屏游戏、Zoom 抢占焦点时大概率漏掉
- 两个 VSCode 窗口之间切换,不算“失去焦点”,不会保存
- 远程开发(SSH/WSL)中,宿主系统上报的窗口焦点事件不稳定,实测触发率下降明显
- 它对未命名、只读、或匹配
files.exclude的文件同样静默跳过
想接近“保存所有修改文件”?只能手动加权衡
VSCode 原生不支持批量保存所有 dirty 文件,但你可以用组合策略降低风险:
- 坚持用
"onFocusChange"+ 合理习惯:频繁在多个文件间切换时,每次切走前都确保当前文件是你要保护的那个 - 配合
workbench.action.files.saveAll快捷键(默认无绑定,可自定义为Ctrl+Alt+S),切走前顺手一按 - 启用
files.autoSave为"afterDelay"并设为1000,再配合files.autoSaveDelay,适合敲代码节奏快、停顿少于 1 秒的人 - 别依赖插件“模拟全量保存”——多数这类插件在文件未激活、只读或路径特殊时行为不一致,反而增加不确定性
最常被忽略的一点:自动保存是否生效,和你当前编辑的文件状态强绑定。不是配置对了就万事大吉,而是每次切走前,VSCode 都会现场校验该文件能否写入——这个判断过程完全静默,没弹窗、没日志、也没状态栏提示。











