用好Emmet提升前端编码效率的实用技巧

欧阳树恺 工具 阅读 727
赞 2 收藏
二维码
手机扫码查看
反馈

说实话,Emmet我只用这一个方案

先说结论:不管你在用什么前端工具链,只要你还在手写HTML结构,Emmet必须给我用起来。而且别整那些花里胡哨的自定义扩展,就用编辑器自带的那一套——VS Code默认的Emmet,够了。

用好Emmet提升前端编码效率的实用技巧

我知道有人折腾过Emmet插件、自定义语法、甚至搞个构建流程预编译Emmet片段。我也试过,结果呢?折腾半天发现根本没必要。你现在写的代码可能五分钟就能生成出来,但我非得花两小时配个“高效”方案,最后还因为版本更新出bug,谁懂啊。

今天我就来聊聊我踩过的几个坑,对比下几种常见的“Emmet玩法”,说说为啥我现在只认默认那一套。

三种常见的“Emmet用法”

第一种:原生Emmet(VS Code内置)

第二种:自定义Emmet snippets(通过JSON配置扩展)

第三种:预编译式Emmet(比如配合Post-HTML或Webpack loader)

听上去好像都挺高级,但真用起来差别可大了。

谁更灵活?谁更省事?

先说最常用的场景:快速写一个列表项结构。比如要做个用户卡片列表。

<ul class="user-list">
  <li class="user-item">
    <img src="avatar.jpg" alt="User Avatar">
    <div class="user-info">
      <h3 class="username">张三</h3>
      <p class="bio">前端打工人</p>
    </div>
  </li>
</ul>

用原生Emmet怎么写?一行搞定:

ul.user-list>li.user-item>(img[src=avatar.jpg][alt="User Avatar"])+.user-info>h3.username+p.bio

敲完 Tab,直接生成。速度快到离谱,关键是不用切换上下文去查配置文件。

再看第二种:我自己写了个 snippets 叫 userCard,绑定到某个前缀。配置长这样:

"userListCard": {
  "prefix": "ucard",
  "body": [
    "<ul class="user-list">",
    "  <li class="user-item">",
    "    <img src="$1" alt="User Avatar">",
    "    <div class="user-info">",
    "      <h3 class="username">$2</h3>",
    "      <p class="bio">$3</p>",
    "    </div>",
    "  </li>",
    "</ul>"
  ],
  "description": "用户卡片列表"
}

看起来不错对吧?输入 ucard 回车,也能出结构。但问题来了:

  • 每个项目都得复制一遍这个 snippet
  • 团队协作时别人没有这个配置,还得教他们装
  • 改个结构要重新打开 snippets.json 编辑,不如直接写快

我试过在三个不同项目里维护这种 snippet,最后统一删了——太累。你不是在写代码,你是在伺候配置文件。

第三种更离谱:有人想让Emmet在构建时预处理。比如写个 .emmet 文件,然后用loader转成HTML。举个例子:

<!-- user-list.emmet -->
ul.user-list>li.user-item*3>img+div.user-info>h3.username{用户$}*3

然后通过一个webpack插件转成真实HTML。听着很酷,但真上项目你就知道多坑:

  • 调试困难:浏览器报错显示的是转换后的行号,定位不到源文件
  • 热更新延迟:改一下要等loader跑一圈
  • 生态支持差:现在主流框架都不推荐这种DSL写法了

我之前在一个静态站项目里用了这种方案,结果每次改完刷新要等8秒……最后换成Pug了,但那是另一个故事了。

核心功能对比:别被花哨功能骗了

很多人觉得自定义方案“功能更多”,其实Emmet原生已经覆盖95%的日常需求了。来看看常用操作:

重复生成?用 * 就行:

li.item*5

生成带文本的内容?用 {}

a[href="#"]{点击这里}

父子嵌套?用 >

nav>ul>li*3>a[href="#"]
`&gt;

&lt;p&gt;兄弟节点?用 +:&lt;/p&gt;</code></pre>plaintext
header+h1.title+p.desc
<pre class="pure-highlightjs line-numbers language-none"><code class="no-highlight language-none">&lt;p&gt;属性自动补全?class和id直接跟在后面:&lt;/p&gt;</code></pre>plaintext
div.container#main.content
<pre class="pure-highlightjs line-numbers language-none"><code class="no-highlight language-none">&lt;p&gt;变成:&lt;/p&gt;</code></pre>html
<div class="container content" id="main"></div>
<pre class="pure-highlightjs line-numbers language-none"><code class="no-highlight language-none">&lt;p&gt;这些操作我在日常开发中每天至少用几十次。关键是:它们是通用的。我去客户现场临时搭环境,只要装个VS Code,默认就有。不像某些snippet,还得导出导入,麻烦死了。&lt;/p&gt;

&lt;h2&gt;踩坑提醒:这三个点我被坑过好几次&lt;/h2&gt;

&lt;p&gt;1. 不要依赖 Emmet 生成完整组件逻辑&lt;/p&gt;

&lt;p&gt;有一次我图快,用Emmet生成了一堆表单项,包括input type、label for、id绑定。结果后来加了个动态name字段,Emmet没法动态处理变量,只能手动改。从那以后我明白了:Emmet只适合静态结构,带逻辑的别硬套。&lt;/p&gt;

&lt;p&gt;2. 注意空格陷阱&lt;/p&gt;

&lt;p&gt;这个坑我踩了不止一次。看这段:&lt;/p&gt;</code></pre>plaintext
div .box
<pre class="pure-highlightjs line-numbers language-none"><code class="no-highlight language-none">&lt;p&gt;注意 div 和 .box 中间有个空格。你以为会生成
<div><div class="box"></div></div>?错,它会生成两个并列元素。正确的应该是:&lt;/p&gt;</code></pre>plaintext
div.box
<pre class="pure-highlightjs line-numbers language-none"><code class="no-highlight language-none">&lt;p&gt;少个空格,结果完全不一样。建议写完立刻预览一眼,别信直觉。&lt;/p&gt;

&lt;p&gt;3. 特殊字符记得转义&lt;/p&gt;

&lt;p&gt;比如你要生成带引号的属性:&lt;/p&gt;</code></pre>plaintext
a[title="点击'这里'"]
<pre class="pure-highlightjs line-numbers language-none"><code class="no-highlight language-none">&lt;p&gt;没问题。但如果里面还有双引号,就得小心了。亲测有效写法是用单引号包住值:&lt;/p&gt;</code></pre>plaintext
a[title='他说"你好"']
<pre class="pure-highlightjs line-numbers language-none"><code class="no-highlight language-none">&lt;p&gt;或者干脆避免复杂文本,后面手动补。&lt;/p&gt;

&lt;h2&gt;我的选型逻辑:能少配就少配&lt;/h2&gt;

&lt;p&gt;我现在选技术方案就一条原则:能不能开箱即用。&lt;/p&gt;

&lt;p&gt;Emmet这种工具,本质是提效的,不是炫技的。你搞得越复杂,后期维护成本越高。尤其是当你换项目、换团队、换电脑的时候,最简单的反而最可靠。&lt;/p&gt;

&lt;p&gt;所以我的选择很明确:用VS Code默认Emmet,不加任何额外配置。除非公司有统一规范要求,否则绝不搞自定义snippets。&lt;/p&gt;

&lt;p&gt;那有人问:要不要装Emmet插件?答案是不需要。VS Code从1.5版本开始就把Emmet内建了,而且支持Vue、JSX、Svelte等各种语法上下文。你要是还单独装个Emmet插件,反而可能冲突。&lt;/p&gt;

&lt;p&gt;顺带一提,WebStorm也内置了Emmet,行为几乎一致。这意味着你在不同IDE之间切换也不会断片。&lt;/p&gt;

&lt;h2&gt;一点妥协:CSS那边我还是开了个例外&lt;/h2&gt;

&lt;p&gt;虽然HTML坚决不用自定义,但CSS方面我给自己留了个后门。因为有些属性组合实在太长了,比如flex布局:&lt;/p&gt;</code></pre>css
display: flex;
align-items: center;
justify-content: space-between;
<pre class="pure-highlightjs line-numbers language-none"><code class="no-highlight language-none">&lt;p&gt;于是我配了个 snippet,前缀叫
fx:&lt;/p&gt;</code></pre>json
"Flex Center": {
"prefix": "fx",
"body": [
"display: flex;",
"align-items: center;",
"justify-content: ${1:center};"
]
}
`

<p>为什么这里肯配?因为:</p>

<ul>
<li>CSS结构稳定,很少变</li>
<li>属性组合高度重复</li>
<li>不会跨语言复用(不像HTML模板)</li>
</ul>

<p>算是我在实用主义面前的一点低头吧。</p>

<h2>以上是我的对比总结,有不同看法欢迎评论区交流</h2>

<p>说到底,Emmet只是个工具。别让它反过来控制你的工作流。我见过太多人花几小时优化编辑器配置,结果当天只写了两行业务代码,真的不值得。</p>

<p>如果你刚开始接触前端,听我一句劝:先把原生Emmet练熟,每天用,形成肌肉记忆。等你真遇到它解决不了的问题,再考虑扩展也不迟。</p>

<p>至于那些花里胡哨的预处理器+Emmet组合拳?放过自己吧。我们现在又不是在2012年写静态页,框架都帮你抽象好了结构,Emmet的任务就是帮你快速搭个原型,别的别指望太多。</p>

<p>最后贴个我常用的速记口诀,放快捷键旁边天天看:</p>

<ul>
<li>
> 子元素</li>
<li>
+ 兄弟元素</li>
<li>
* 重复次数</li>
<li>
{} 文本内容</li>
<li>
[] 自定义属性</li>
<li>
# id</li>
<li>
.` class

记牢这几个,够用三年。其他的,边用边学就行。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论