vue sfc缩进错位的根本原因是vscode默认无法分段识别template/script/style,必须依赖volar提供语言服务+prettier执行格式化,且需配置"[vue]": {"editor.defaultformatter": "esbenp.prettier-vscode"}和"prettier.parser": "vue"确保模板按vue语法解析。

Vue 项目缩进混乱,不是 VSCode 不行,而是默认不处理 Vue 模板语法的缩进逻辑 —— 必须靠 Prettier + Volar 组合,且 editor.formatOnSave 要配合语言专属配置才生效。
为什么 Vue 单文件组件(SFC)缩进总错位?
VSCode 自身的 editor.autoIndent 只管 JS/TS 的换行缩进,对 <template></template> 和 <script setup></script> 内部结构完全无感知。常见现象包括:
<div> 嵌套后粘贴进去整块缩进不变,导致层级断裂 <li> <code>v-for内部元素回车后光标停在行首,而非自动缩进到父级下一级- 保存时
<style></style>段落缩进了,但<template></template>还是扁平的 -
Volar(作者:Vue Language Features):提供 Vue 专属语言服务,让 VSCode 知道
<template></template>是模板、<script setup></script>是 TS、<style></style>是 CSS —— 这是分段格式化的前提 -
Prettier(作者:esbenp.prettier-vscode):负责实际执行缩进与对齐,它通过 Volar 提供的 language ID(如
vue-html、vue)调用对应规则
根本原因:Vue SFC 是多语言混合体,VSCode 默认只把整个文件当 “HTML” 或 “Vue” 处理,而真正能分段识别 template/script/style 并分别格式化的,只有 Volar(非旧版 Vetur)+ Prettier 插件协同工作。
必须安装并启用的两个扩展
缺一不可,且顺序和启用状态直接影响缩进是否生效:
验证是否生效:打开一个 .vue 文件,右下角状态栏点击语言模式,确认显示的是 Vue(不是 HTML 或 Plain Text);再按 Shift+Alt+F,如果弹出 “Formatting with Prettier” 提示,说明链路通了。
关键 settings.json 配置项
以下配置必须写入工作区 .vscode/settings.json(而非用户全局设置),否则在多人协作项目中极易失效:
{
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.detectIndentation": false,
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"prettier.parser": "vue",
"prettier.singleAttributePerLine": true,
"prettier.htmlWhitespaceSensitivity": "ignore"
}
注意点:
-
"[vue]"块必须存在,它覆盖了文件级语言设置,确保 Vue 文件强制走 Prettier -
"prettier.parser": "vue"是硬性要求,否则 Prettier 会把<template></template>当成普通 HTML 处理,缩进层级全乱 -
"prettier.htmlWhitespaceSensitivity": "ignore"防止 Prettier 把模板中用于对齐的空格误删,尤其影响<div><span> 类嵌套可读性 <h3>容易被忽略的三个坑</h3> <p>即使上述都配对了,仍可能缩进失败,问题往往藏在这三处:</p> <ul> <li>项目根目录有 <code>.prettierrc但没写"parser": "vue"—— VSCode 会优先读该文件,导致 parser 设置被覆盖 - 同时装了 Vetur 和 Volar —— 二者冲突,Volar 会被禁用,右下角语言模式显示为
Vue (Vetur),此时vue-html语言 ID 不可用,Prettier 格式化直接跳过 template 段 -
<script setup lang="ts"></script>中用了未声明的类型(如ref<xxx>()</xxx>),Volar 解析失败,整个 script 段格式化中断,连带影响 template 缩进上下文
最稳妥的验证方式:临时删掉 .prettierrc,关闭所有其他 Vue 相关插件,只留 Volar + Prettier,用最小配置跑通一次,再逐步加回团队规范。











