欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

node入门(六) - express(模板引擎 Handlebars)

程序员文章站 2022-06-19 11:33:39
...

模板引擎

上章说过,安装生成器后,就可以使用命令行
express -v hbs -c less
这里的v指的view ,
可选:(ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
因为jade太难用,
ejs和jsp语法一样(<%%>、<%=%>、<% include %>)。自身也掌握(需要了解,后面会出jsp el表达式),这里就详细说明hbs(Handlebars),并且相对于ejs,会默认有个导航条。

//在views\layout.hbs
<body>
    导航{{{block nav}}}
    <hr/>
    {{{body}}}
  </body>

 默认其他页面就是加载到{{{body}}}中
如果你也是使用IEDA或者webStrom,
可以安装插件:ejs和Handlebars/Mustache 

语法

#each、 #if、#with
@first、@last、@index、@key、@root
path
{{!}} 里面是注释,
data.[0].xx

在routes/index.js中

不清楚项目结构,可以参照上章,或者自己安装

通过render,将数据携带到views下index.hbs的模板中
router.get('/', function (req, resp, next) {
    resp.render('index', {
        data: {name:'-- 我在测试',id:5},
        arr:['张三','33','170cm'],
        objArr:[{
            id : 5,
            weight : 110,
            visibility : false
        },{
            id : 9,
            weight : 120,
            visibility : true
        }]
    });
});

在views/index.hbs中

现在来展示数据
// 首先是循环
<h3>循环数组</h3>
{{#each arr}}
    <!--this指向arr中的value-->
    {{this}}<br/>
{{/each}}

<h3>循环简写方式</h3>
{{#arr}}
    {{this}}<br/>
{{/arr}}

此时页面两个都会输出一样的结果,但是不建议用简写方式

循环数组

张三
33
170cm

测试复杂json数据解析

<h3>测试Json</h3>
{{#each objArr}}
    <!--
    this可以省略,其实是{{this.id}}--{{this.weight}}
    --> 

    {{id}}- - {{weight}}--

    <!--
    可以将对象中的布尔值当做条件使用
    注意:if都只接收true,如1==1 是不能使用的(使用registerHelper解决,下面会说)
         #if else /if 中间else没符号
    --> 

    {{#if visibility}}
        这是可见的
    {{else}}
        这是不可见的
    {{/if}}<br/>
{{/each}}

此时页面展示的数据为

测试Json

5- - 110-- 这是不可见的 
9- - 120-- 这是可见的 

对比下each和with

<h3>遍历数组内的对象</h3>
<!--就只能用#each 不能使用简写#objArr.[0]-->
{{#each objArr.[0]}}
    {{this}}
{{/each}}<br/>

{{#with objArr.[0]}}
   <!-- {{@key}}<br/>-->
    {{this.id}} -- {{this.weight}}
{{/with}}

此时页面的输出结果为
with和each作用域不一样,with中的this就指向其本身

5 110 false 
5 -- 110

@first,@last,@key,@index

{{#each objArr}}
    <[email protected]/@index 默认从0开始
    @first 判断是不是第一行
    还可以判断@last 是不是最后一行
    -->
    {{@key}}
    {{@index}}

    {{@first}} --  {{id}} -- {{weight}}<br/>
 {{/each}}

此时页面的输出结果为

0 0 true  -- 5 -- 110
1 1 false -- 9 -- 120

@index和@key的区别

{{#each objArr.[0]}}
    {{@key}} -- {{@index}}
{{/each}}<br/>
//id -- 0 weight -- 1 visibility -- 2
//@key 还可以遍历对象

@root

{{#each arr}}
<[email protected]在数组内,那与父级相同的元素
    两种写法
-->
    <!--{{../data.name}} <span>: 第一种支持路径</span>
    {{@root.data.name}} <span>: 第二种@root</span>
{{/each}}

拿出数组中元素的示例-

{{objArr.[0].weight}}

registerHelper自定义

在routes/help.js中

var express = require('express');
var router = module.exports = express.Router();

var hbs = require('hbs');
/**自定义等于
 * @context 代表表达式中的引用上下文
 * @fn 代表正确返回的内容
 * @context.fn(this)中this指向resp.render返回的数据
 * */
hbs.registerHelper('eq', function (n1,n2,context) {
    if(n1==n2){
        // return context.fn(n1===n2);
        return context.fn(this);//this 代表传原始的数据
    }
    /*不满足条件,保证能显示页面中元素*/
    return context.inverse(this);
});

// 此处为官方自定义导航条
var blocks = {};

hbs.registerHelper('extend', function(name, context) {
    var block = blocks[name];
    if (!block) {
        block = blocks[name] = [];
    }

    block.push(context.fn(this));
});

hbs.registerHelper('block', function(name) {
    var val = (blocks[name] || []).join('\n');
    blocks[name] = [];
    return val;
});

// 现有
router.get('/',function (req,resp) {
    resp.render('help',{
        title : '--这就是测试--'
    });
});

在views/help.hbs中

<h1>内容</h1>
<!--只是输出数据-->
<hr>
{{#eq 1 1}}
    <!--
    Top{{this}}Bottom 得到路由中传入的n1===n2的结果
    -->
    Top{{this.title}}Bottom
{{else}}
    条件不满足
{{/eq}}
<hr>

<!--此处是配合layout.hbs增加导航条-->
{{#extend nav}}
    <button>填洞</button>
{{/extend}}

在layout.hbs中

<!DOCTYPE html>
<html>
  <head>
    <title>{{title}}</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <!--新增加导航条-->
    导航{{{block nav}}}
    <hr/>
    {{{body}}}
  </body>
</html>