在这篇文章中我们将对 JavaScript 模板进行概述。我们将首先讨论 JavaScript 模板是什么,何时使用它们,如何使用它们,在深入更多细节前,看看一些流行的模板引擎。我们将关注 Mustache, Handlebars 和 jQuery Template。
什么是JavaScript模板
JavaScript 模板是将 HTML 结构从包含它们的内容中分离的方法。模板系统通常会引入一些新语法,但通常是非常简单的,特别是如果我们以前已经在其他地方使用过模板系统(如 PHP 中的 Twig )。一个要注意的有趣的点是,替换标记通常是由双花括号({ {……} })表示,这也是 Mustache 和 Handlebars 名字的来源(提示:从侧面看它们的相似之处)。
什么时候使用JavaScript模板?
一旦我们发现自己在 JavaScript 字符串内包含 HTML,就应该开始考虑 JavaScript 模板可能给我们带来的好处。当建立一个可维护的代码库,关注点分离是至关重要的,所以任何可以帮助我们实现这一目标的手段都应该探索。在前端 web 开发,将 HTML 从 JavaScript 分离显得很重要(这是双向的,我们也不应该在 HTML 中内联 JavaScript)。
一些可以受益于 JavaScript 模板的常见场景是实时 web 应用程序(例如一个事件评论的直播应用),或国际化(i18n),它们通常要求使用相同的格式显示不同的内容。
如何使用 JavaScript 模板?
我们将通过特别的库案例详细介绍它,但本质上这和包含我们选择的库一样简单,即获取模板和使用一些数据渲染它。
大多数库支持内联和外部模板。内联模板在只有很少模板时非常适合,或者当每个加载的页面都需要使用模板,但是通常我们的模板应该是外部模板。外部模板带来很多好处,主要是模板永远不会被下载到客户端,除非它们被页面所需。
mustache.js
Mustache 是一个多语言,逻辑简单的模板系统。mustache.js 只是其中一个实现。一旦我们习惯了(非常简单的)语法,就可以在各种各样的编程语言中使用它。
关键点
- 文件9kb大小(很小)
- 简单
- 无依赖
- 无逻辑
- 非预编译模板
- 编程语言无关
举例
1 2 3 |
<script id="template" type="x-tmpl-mustache"> <p>Use the <strong>{{power}}</strong>, {{name}}!</p> </script> |
1 2 3 4 5 6 7 8 9 10 11 |
//Grab the inline template var template = document.getElementById('template').innerHTML; //Parse it (optional, only necessary if template is to be used again) Mustache.parse(template); //Render the data into the template var rendered = Mustache.render(template, {name: "Luke", power: "force"}); //Overwrite the contents of #target with the rendered HTML document.getElementById('target').innerHTML = rendered; |
正如你在这个例子中所看到的,Mustache.render 函数接受两个参数:Mustache 模板,以及一个包含所需的数据和代码的视图对象,它用于渲染模板。在这个案列下,我们使用简单的字符串替换name和power变量,但它可以做得更多。例如 循环遍历一个数组,或者使用 特别的渲染函数,使用当前视图作为其视图参数。
mustache.js 非常适合小型项目和模板复杂性较小的快速原型。需要关键注意的是,我们可以在一个项目开始时使用 mustache.js,然后轻松升级到 Handlebars.js,因为它们的模板(大部分)是相同的。
如果你想阅读更多关于 Mustache 的内容,看看 使用Mustache.js创建HMTL模板。
Handlebars.js
Handlebars.js 构建在 Mustache 之上,与Mustache模板大部分兼容。简而言之,它提供了 mustache.js 提供的一切,加上它支持块表达式和预编译模板。预编译模板是了不起的东西,因为它们大幅提高性能(在一个粗略的性能测试,预编译的 Handlebars.js 模板渲染的时间是Mustache模板的一半)。块表达式允许您在模板中包含更多的逻辑,更常见的例子之一是高级迭代——比如,创建一个 <ul> 列表迭代器,它将每个条目用 <li> 包装。你可以在这里阅读更多关于块表达式的内容。
关键点
- 86kb文件大小(大),或者使用预编译模板是18kb
- 块表达式(helpers)
- 预编译模板
- 无依赖
举例
1 2 3 |
<script id="template" type="text/x-handlebars-template"> <p>Use the <strong>{{power}}</strong>, {{name}}!</p> </script> |
1 2 3 4 5 6 7 8 9 10 11 |
//Grab the inline template var template = document.getElementById('template').innerHTML; //Compile the template var compiled_template = Handlebars.compile(template); //Render the data into the template var rendered = compiled_template({name: "Luke", power: "force"}); //Overwrite the contents of #target with the renderer HTML document.getElementById('target').innerHTML = rendered; |
Handlebars.js 很适合性能要求高的项目,同时对于页面增加 18 kb 并不太担心。如果我们想使用块表达式,这也是选择它的原因。
注意,要获得 Handlebars.js 的性能优势(和大大减少的文件大小)我们必须使用 预编译模板。为了有效地这样做,我们应该将Handlebars.js模板预编译添加到构建过程中(Grunt对此有一个很棒的插件)。
如果你想了解更多关于 Handlebars 的内容,看看:Handlebars初学者指南
jQuery Template
jQuery Template没有mustache.js或Handlebars.js流行,但也不要忽视它。它的模板和Mustache模板不同,只是普通的HTML,没有新语法。它不使用标记替换技术,而使用数据属性来表示数据应该插入到HTML片段的位置。
关键点
- 7kb文件大小(小)
- 需要jQuery (大于82kb)
- 简单,但与Mustache以及Handlebars.js的工作方式不同
- 没有预编译模板
举例
1 2 3 4 5 6 |
<script id="template" type="text/html"> <p> Use the <strong data-content="power"></strong>, <span data-content="name"></span>! </p> </script> |
1 2 3 4 5 6 7 8 9 10 11 |
//Call .loadTemplate() on the target container $('#target').loadTemplate( //Specify the template container (or file name of external template) $('#template'), //Specify the data to render { name: "Luke", power: "force" } ); |
jQuery Template对于已经使用jQuery的项目很合适,因为文件大小非常小。但是如果你的项目不使用jQuery,考虑到总文件大小就不便推荐使用。
其他选择
当然还有很多其他解决方案可以解决这个问题,我们不会在本文中详细讨论。这里有一个一些其他受欢迎的选择的快速概述:
Underscore.js
Underscore是一个流行的JavaScript库,在无数的其他特性下它提供模板函数。默认情况下,它不使用Mustache的双花括号语法,而是选择 ERB-style的分隔符(< %…% >)。
Embedded JS Teamplates(EJS)
像Underscore.js,Embedded JS Templates使用ERB-style模板语法。EJS需要注意的一件事情是,必须是外部文件——他们不能有内联模板。
结束语
所以哪个是最好的?像大多数开发问题一样,没有银弹。这取决于很多事情:
- 你是否已经在项目中使用jQuery?
- 你之前使用过哪种模板系统?
- 你是否想把逻辑从模板中分离?
- 你对页面文件的整个大小有多担忧?
- 你对性能有多担忧/你的网站是否需要支持低能耗设备?
一旦我们思考这些因素,就可以从上面的列表做出合理的选择。然而之前简单地提到过,一个好的灵活的策略是先使用mustache.js,之后有功能添加或性能需求,再过渡到Handlebars.js。
想发表什么见解吗?请在下面留下你的评论!