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>
上一篇: stat