模板引擎的作用:需要动态渲染大量html的时候,用js代码手动写入,不仅会失去代码高亮显示,而且在js代码中加入太多的html标签字符串会导致代码阅读的复杂度。此时就使用模板引擎
选择模板引擎的准则:
- 模板引擎的性能: 要快
- 跟据你的项目,看模板引擎服务端和客户端的兼容情况
- 希望语法抽象还是具体(既语法规则与html语法是否接近)
handlebars
npm i express-handlebars
const express = require('express')
var exphbs = require('express-handlebars')
...
// 对模板引擎进行默认配置
app.engine('handlebars', exphbs())
// 将默认的引擎设置为handlebars
app.set('view engine', 'handlebars')
布局文件:handlebars引擎默认的布局文件是/views/layout/main.handlebars
文件
视图文件:放在/views
文件加下面。直接通过res.render('filename')
就可以找到
局部文件:放在/views/partials/
文件夹下面,可以引入到其它的视图文件中,通过{{> filename}}
的形式引入。
注释:{{! 注释内容}}
段落:只用在访问特定路由时,才会把代码片段插入到页面中。
// 在入口文件中加一个这样的片段
var handlebars = require('express-handlebars').create({
defaultLayout:'main',
// extname: '.hbs',
// default: 配置默认布局; 默认为views/layout/main.handlebars
// extname: 配置文件扩展名;使handlebars文件可以使用这个扩展名
helpers: {
section: function(name, options){
if(!this._sections) this._sections = {};
this._sections[name] = options.fn(this);
return null;
}
}
})
app.engine('handlebars', handlebars.engine)
app.set('view engine', 'handlebars')
片段的内容写在具体的路由文件中
{{#section 'head'}}
<!-- we want Google to ignore this page -->
<meta name="robots" content="noindex">
<style>
h1 {
color: red
}
</style>
{{/section}}
<h1>Test Page</h1>
<p>We're testing some jQuery stuff.</p>
{{#section 'jquery'}}
<script>
$('document').ready(function(){
$('h1').html('jQuery Works');
});
</script>
{{/section}}
插入片段卸载布局文件中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Meadowlark Travel</title>
{{{_sections.head}}}
<script src="/js/jquery-1.12.2.js"></script>
</head>
<body>
<h1>这是布局文件</h1>
{{{body}}}
{{{_sections.jquery}}}
</body>
</html>
{{body}}
和{{{body}}}
的区别:前者会将其它在布局中引入的文件全部以不普通字符串的形式显示,而不会渲染成html。包括在其它视图中引入的局部视图
语法块:
<h2>块级表达式</h2>
<ul>
{{! 我是注释 --下面的语句块是用于循环数组}}
{{#each tours}}
{{! 这里的上下文就变成了tours的每一项}}
<li> {{name}} - {{fee}}
{{! ../表示返回上一级上下文,既顶级上下文--注意不是数组tours}}
{{../currencies}} {{! 会把currencies数组的每一项都打印一份}}
{{#if ../currencies}}
{{! ../../currency.name }}
({{name}}) {{! 在 if或者else的语句块中,会产生一个上级上下文的副本-可以理解为它的上下文和上一级上下文是一样的}}
({{../grade}}) {{! 1 再返回一级上下文就到顶级上下文了}}
{{/if}}
</li>
{{/each}}
</ul>
{{#unless currencies}}
<p> All Prices in {{currency.name}}</p>
{{/unless}}
{{! if循环语句}}
{{#if specialPlace}}
<p>{{specialPlace}} 是我上班的地方</p>
{{/if}}
{{#each currencies}}
<p>条件一: {{.}}</p>
{{else}}
<p>条件二: {{currency.name}}</p>
{{/each}}
-
循环
{{#each 变量名}} ...循环体... {{/each}}:循环中的上下文变成循环中的每一项
-
条件:
{{#if}} ...条件判断的执行语句... {{/if}} : 条件中的上下文是上一级上下文的副本,仍然是上一级上下文
{{#unless}}...{{/unless}}
-
在某一个上下文中:通过
../
可以返回上一级上下文