JS模板引擎---mustache与HandleBars

来源:互联网 发布:大数据与传统制造业 编辑:程序博客网 时间:2024/05/29 18:42

JS模板引擎—mustache与HandleBars

以前总听说模板引擎这个东西然而却没有研究过,这两天研究了一下模板引擎,最开始接触了mustache,它是一个客户端的模板引擎。 然后想了解一下服务端模板引擎,最开始接触了Jade发现这货太抽象风格不适合我。最后选择了 HandleBars 这款模板引擎。 它是mustache的一个扩展,支持客户端和服务端,很强大很好用,具体在客户端和服务端怎么使用,下面我给大家详解。

  • 先说说mustache吧
    1.引入
    可以在github上获取相关的Mustache.js的文件然后再script标签引入
    或者使用 CDN 如下示范
<script src="http://cdn.bootcss.com/mustache.js/2.2.1/mustache.min.js"></script>

2.使用
{{#}} {{/}} 见下代码

    var myData = {        students : [            {name : 'ruihao', years : 20, sex: 'man'},            {name : 'jiahua', years : 21, sex: 'man'},            {name : 'qinjie', years : 20, sex: 'woman'}        ]    };    var template = "<div><table><tr><td>name</td><td>years</td><td>sex</td></tr>{{#students}}<tr><td>{{name}}</td><td>{{years}}</td><td>{{sex}}</td></tr>{{/students}}</table></div>";    var viewTemplate = Mustache.render(template, myData);    container.innerHTML = viewTemplate;

代码解释:
{{#student}} {{/student}} 实际上构成了一个循环,会遍历student这个数组,这个数组的每一个元素都是一个对象,所以每个对象的name,years,sex属性都会输出。 注意一下Mustache.render这个函数它接收两个参数:第一个是模板字符串,第二个是这个模板字符串的上下文对象,作为模板字符串的数据来源
最后页面为:
ruihao 20 man
jiahua 21 man
qinjie 20 woman


实际上{{#}} {{/}}不光有循环数组的作用。还有判断null/false/undefined的作用,如果为null/false/undefined 那么则不渲染

    var myData = {        students : [            {name : null, years : 20, sex: 'man'},            {name : 'jiahua', years : 21, sex: 'man'},            {name : 'qinjie', years : 20, sex: 'woman'}        ]    };    var template = "<div><table><tr><td>name</td><td>years</td><td>sex</td></tr>{{#students}}<tr><td>{{#name}}{{name}}</td><td>{{years}}</td><td>{{sex}}{{/name}}</td></tr>{{/students}}</table></div>";    var viewTemplate = Mustache.render(template, myData);    container.innerHTML = viewTemplate;

那么得到的结果会是
jiahua 21 man
qinjie 20 woman

{{{}}} 三层花括号的使用
防止被模板被转译
话不多说上代码

    var myData = {        spanC : '<span>hahaha</span>'    };    var template = "<div>{{{spanC}}}</div>";//三层花括号就不会转译    var viewTemplate = Mustache.render(template, myData);    container.innerHTML = viewTemplate;

最后页面上显示的就是 </span>hahaha</span>
如果是两层花括号,那么span标签就会被解析 最后在页面上只有 hahaha

再谈遍历数组
之前我们说了用 {{#}} {{/}}去遍历数组。我们仔细观察可以发现,我们用{{#}} {{/}}去遍历的每个数组元素都是一个对象。那么如果不是一个对象呢? 怎么办? 参见以下代码

    var myData = {dataArr : ['ruihao', 'ruixin', 'qinjie']};    var template = "<div>{{#dataArr}}<p>{{.}}</p>{{/dataArr}}</div>";    var viewTemplate = Mustache.render(template, myData);

这里用{{.}} 去遍历数组。

大概到这里mustache的东西就总结完了,还有部分语法没说到,大家可以百度或者谷歌吧。


接下来说说 HandleBars,这个就很有意思了,语法和 Mustache很像,首先先不谈语法,我们从服务端的HandleBAR开始说起

我在服务端使用HandleBars时候是搭配 Express写的。
首先先安装 HandleBars

npm install --save express3-handlebars

在Express中引入HandleBars模板引擎

var express = require('express');var app = express();var handlebars = require('express3-handlebars')                .create({                    defaultLayout : 'main'//设置默认布局为main                                 });                // extname : 'hbs' //设置模板引擎文件默认后缀,为.hbs,如果大家.handlebars 这么长的后缀不习惯的话可以用 extname这个属性改后缀。 加到 create函数里接收的那个对象就行app.engine('handlebars', handlebars.engine); //将Express的模板引擎设置为handlebarsapp.set('view engine', 'handlebars');

讲完了如何安装和在Express中引入HandleBars接下来我们需要了解一些概念问题。
我们需要明白视图和布局。
视图 :视图通常表现为网站上的各个页面。默认情况下,Express 会在views 子目录中查找视图。
布局 :布局是一种特殊的视图,事实上,它是一个用于模板的模板。布局是必不可少的,因为站点的大部分(即使不是全部)页面都有几乎相同的布局。
我们来看一种布局模板。 看看布局到底是怎么样的

<!DOCTYPE html><html><head>    <title></title>    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></head><body>    {{{body}}}</body></html>

注意{{{body}},有了 {{{body}}} 那么模板引擎就知道在哪里渲染视图了
在这里我们使用了三层花括号而不是两层。同学们应该有印象,就是我们在介绍mustache模板引擎时说过 三层花括号不转译~ 这个规定在HandleBars中同样适用。

那么模板引擎到底是怎么结合视图和布局完成渲染的呢?

我们看看下图,它详细的解释了顺序
大家观察可以发现。 模板引擎首先渲染了视图然后才渲染布局。
看起来有点反常吧。因为不应该是视图(view)在布局(layout)中渲染吗?不要奇怪了。 逆向渲染也是有优势的!
渲染顺序解释图


模板引擎会在views目录下寻找视图。在 views/layouts/下寻找布局

好了说了这么多到底怎么用嘛。不多说上代码

//app.jsvar express = require('express');var app = express();var handlebars = require('express3-handlebars')                .create({                    defaultLayout : 'main'//设置默认布局为main                                 });                // extname : 'hbs' //设置模板引擎文件默认后缀为.hbsapp.engine('handlebars', handlebars.engine); //将Express的模板引擎设置为handlebarsapp.set('view engine', 'handlebars');app.use(function (req, res, next){    res.locals.rui = {        name : 'ruihaolee',        years : 20,        direction : 'web'    };//res.locals 规定渲染视图的默认上下文    next();});app.get('/ruihao', function (req, res){    res.render('ruihao', {layout : 'main'});    // res.end();不能有end。否则报错});app.listen(3689);

大家注意一下 res.render('ruihao', {layout : 'main'});
这句代码意思就是说: 在views下寻找 ruihao.handlebars这个视图
在 views/layouts/下寻找 main.handlebars这个布局

还有一个就是res.locals ,它规定了渲染视图的上下文。因此我们在上面的代码加了一个中间件规定了上下文

通过我的测试:不能有res.end(), 否则会报错。我觉得可能是因为还没有渲染完模板就结束了响应所以报错。
附上整个目录(我怕有的同学一头雾水)
这里写图片描述
附上一个视图ruihao.handlebars 和 布局 main.handlebars的代码

//ruihao.handlebars{{#rui}}    <div>{{name}}</div>    <div>{{years}}</div>    <div>{{direction}}</div>{{/rui}}
//main.handlebars<!DOCTYPE html><html><head>    <title></title>    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></head><body>    {{{body}}}</body></html>



对了补充一个。有些时候我们可能在很多页面使用相同的组成部分,使用模板引擎有一个解决办法就是使用局部文件
模板引擎会在views/partials 中找局部文件
在视图中可以通过 {{>xxx.handllebars}}去引入。并且和视图使用相同的作用域。

好了。 服务端的HandleBars的使用大概就是这样子


客户端的HandleBars
最后一个就是客户端使用handlebars了。 和Mustache一样。从github上得到 handlebars.js的文件或者使用CDN加速来引入。
语法暂且先不谈。让我们看看使用的特点吧
我们有一个特殊的script标签。看如下代码

<script id="tpl-ruihao" type="text/x-handlebars-template">  //我们要个这个script标签一个特殊的Id,方便一会去获取它<div class="demo">          <h1>{{title}}</h1>        <p>{{content.title}}</p>    </div></script>  

然后再我们的JS文件中这样去配合

    var source = document.getElementById('#tpl').innerHTML;    //获取到那个特殊的script标签。    var template = Handlebars.compile(source); //预编译模板    var context = { name: "zhaoshuai", content: "learn Handlebars"};//模拟json数据    var html = template(context);//将context这个对象作为上下文给模板并得到编译好的Html    document.body.innerHTML = html;

使用的方法相信同学们都看懂了吧,是不是很有意思哈哈~
具体的语法其实和Mustache挺像的,因为handlebars 就是 mustache的拓展嘛。我在这里也就不多说了。我觉得重要的还是使用方法吧
我给同学们一个链接大家可以去看看,讲handlebars的语法讲的挺好的

Handlebars语法文档

写了好多了就到这里结束吧。如果上文有什么说的不对的地方希望大家指出来。谢谢啦

2 0
原创粉丝点击