Emmet这东西,用好了是真快,用不好就是各种按不下去的尴尬。很多人在群里问“为什么我写的缩写没反应”,答案往往不是缩写本身的问题,而是几个非常基础的细节没对齐。今天就把这几个最容易卡住人的点掰开揉碎了讲清楚。
Emmet 不是万能缩写手册,它只在语言模式正确、语法精准、上下文匹配时才可靠展开;所谓“万能”其实是误读,真正高效的是掌握三类结构逻辑 + 两个关键配置。

为什么 div.container>h2.title+ul.list>li*3 按 Tab 没反应
你写了一个很标准的缩写,Tab键按下去,结果光标纹丝不动。这时候千万别急着怀疑自己是不是写错了——先看看编辑器右下角的状态栏,语言模式是不是 Plain Text 或者 Ja vaScript?如果是,点一下把它切到 HTML,问题就解决了。文件没保存、后缀名缺失时,VSCode会默认当成纯文本处理,这也是一个常见陷阱。
另一个容易被忽略的原因:你装的插件太多了。Prettier、Auto Rename Tag 这些插件可能会“劫持”Tab键,导致Emmet根本没机会响应。去 settings.json 里翻一下,看看有没有 "emerald.emmetEnabled": false 这种旧配置残留,或者 emmet.triggerExpansionOnTab 被改成了 false。默认它是 true,但不少人之前为了调别的功能顺手改过,后来就忘了。
ul>li*5 和 ul>li{Item $}*5 的实际差异
这两个缩写看起来差不多,但输出结果差别很大,关键在于花括号和计数符的位置。
ul>li*5只会生成5个空,里面什么内容都没有。ul>li{Item $}*5则会生成到- Item 1
,- Item 5
$是自动递增的计数符,必须写在花括号内部。- 注意:
li {Item $}*5中间多了一个空格,这个缩写就直接失效了,Emmet会把它当成两个独立元素处理。 - 同理,
a[href="#"]{Click}是有效的,但a [href="#"]{Click}中间的空格会让解析器认为a是一个独立标签,后面的内容全部被忽略。
在 Vue/JSX 中让 section>div>p 正常展开
Vue单文件组件和JSX默认是不启用Emmet的,必须手动告诉VSCode“这里也当HTML处理”。
- Vue的
区域:需要在settings.json里添加一条映射:"vue-html": "html"。 - JSX文件(.jsx/.tsx)中写元素:添加
"ja vascriptreact": "html",注意是ja vascriptreact,不是ja vascript。 - Vue的
块里如果写了JSX片段(比如render()函数),同样依赖ja vascriptreact这个映射才能生效。 - 另外,Volar插件已经取代了Vetur,如果还在用Vetur,建议换成Volar,否则
区域可能被识别为vue而非vue-html,Emmet照样不响应。
! 生成的 HTML5 模板为什么缺
很多人在VSCode里敲 ! 然后按Tab,发现生成的HTML模板里没有 ,以为是bug。其实这是VSCode内置的 ! 缩写默认输出的是精简版 html:5,它等价于 html:5,输出结构就是 ,确实没有charset声明。
如果你需要一个带charset声明的模板,可以在 settings.json 里覆盖变量:"emmet.variables": { "charset": "UTF-8" }。注意不要误删整个 emmet.variables 对象,否则可能影响其他自定义变量,比如 lang。修改完配置后不需要重启VSCode,但得新建一个.html文件再试 !,已有文件可能会缓存旧行为。
说到底,Emmet能让你多快,完全取决于这些细节有没有对齐。语言模式对不对、光标位置对不对、输入法是不是中文、settings.json里有没有被偷偷改过的配置——这些才是真正卡住人的地方。缩写记再多,基础没打好,也是一样按不出东西。