基本说明(使用过exress和handlebars的可以略过):express中的handlebars引擎是这么生成页面的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/* layout.hbs * 主模板,所有的的页面都将替换"{{{body}}}","{{}}"相当于占位符,由数据进行替换 */ <!DOCTYPE html> <html> <head> <title>{{title}}</title> </head> <body> {{{body}}} </body> </html> /* index.hbs * 单个页面模板,这里以首页为例。"{{>}}"表示引用其他模板来替换,这里引用名为"partial"的模板 */ <div>index</div> {{>partial}} /* partial.hbs * 一个分页文件,被其他模板引用,分页之间也可以互相引用。 */ <div>123</div> /* index.html * 当浏览器请求index.html时,经过handlebars模板引擎处理后生成的页面 */ <!DOCTYPE html> <html> <head> <title></title> </head> <body> <div>index</div> <div>123</div> </body> </html> |
实现步骤1:模板
react的火热让“组件化”的概念持续升温,不过组件化确实在开发中提供了高可复用的代码,大大减少了工作量和bug,确实值得提倡。举个例子。
1 2 3 4 5 |
<ul class="titles border" id="navigator"> <li class="title">标题1</li> <li class="title">标题2</li> <li class="title">标题3</li> </ul> |
这一段html代码,会在几个页面用到,如果按照一般的做法把这段代码ctrl-c、ctrl-v到要用的页面。就会出现两个问题:1.重复代码增多(ctrl-c、ctrl-v应该是程序员的大忌),当然这不是最重要的,最重要的是第2点——维护性差。如果现在我要把“标题1”改成“标题0”,那么只能进行全量搜索然后替换,不仅操作麻烦而且容易出错。 如果用到了模板技术的话这个问题就很好解决,把上面那一段代码写成一个模板,在handlebars中我们成为分页,然后需要这段的代码的页面引用这个分页,如果要修改的话直接修改分页了。以handlebars为例:
1 2 3 4 5 6 7 8 9 |
//navigator.hbs <ul class="titles border" id="navigator"> <li class="title">标题1</li> <li class="title">标题2</li> <li class="title">标题3</li> </ul> //在index.hbs中引用 {{>navigator}} |
为什么handlebars?本文所用的后端模板引擎都以handlebars为例,原因是上次听去哪儿前端团队做的关于node.js的技术分享,炫耀了一个自己基于handlebars实现的小功能:分页中引用的css文件可以全部放到head中。心中一直觊觎这个小功能,直到最近和“组件化”的概念结合在一起考虑,发现这个功能对于实现后端的组件化很有帮助。自己对handlebars也略有研究,所以试着用handlebars来实现一下“组件化”。
实现步骤2:打包
这样就完美了么?no~no~no~ 上面的这一段html代码中可是有样式的,按照w3c的规范,样式应该写在css文件中,怎么实现?自然而然想到两种解决办法:
- 在分页中加入link标签来引入所需的样式,想一想html代码中到处穿插link标签是什么感觉~且不说生成页面难以维护,浏览器渲染速度也会受影响。
- 把分页所需的样式放在公共的样式文件中,这是目前我们项目的通用做法,纯粹的懒人策略,缺点很明显,很多页面引用了一些无用的样式,浪费网络带宽,尤其当项目变大时这个缺点将更加明显。 所以最好的解决方法是按需加载,只加载引用组件所需的样式,当然样式文件按分页拆分得这么细的话会增加请求数,影响不会太大,如果想优化的话也可以压缩合并成一个请求,这个后面再说。 handlerbas中常见的扩展方式就是编写helper,我们可以编写一个helper,
1 2 3 4 5 6 |
//app.js hbs.registerHelper('css', function(str, option) { //在上下文中创建一个数组用来保存该页面需要用到的css文件 this.cssList = this.cssList || []; this.cssList.push(str); }); |
这个helper的作用就是注册一个名为”css”的helper,帮我们保存分页中用到的css文件地址。然后我们在主模板layout的head标签部分遍历cssList数组循环加载出来。
1 2 3 4 5 6 7 8 9 |
//layout.hbs <head> <title>{{title}}</title> {{#each cssList}} <link rel="stylesheet"
实现步骤1:模板react的火热让“组件化”的概念持续升温,不过组件化确实在开发中提供了高可复用的代码,大大减少了工作量和bug,确实值得提倡。举个例子。
这一段html代码,会在几个页面用到,如果按照一般的做法把这段代码ctrl-c、ctrl-v到要用的页面。就会出现两个问题:1.重复代码增多(ctrl-c、ctrl-v应该是程序员的大忌),当然这不是最重要的,最重要的是第2点——维护性差。如果现在我要把“标题1”改成“标题0”,那么只能进行全量搜索然后替换,不仅操作麻烦而且容易出错。 如果用到了模板技术的话这个问题就很好解决,把上面那一段代码写成一个模板,在handlebars中我们成为分页,然后需要这段的代码的页面引用这个分页,如果要修改的话直接修改分页了。以handlebars为例:
实现步骤2:打包这样就完美了么?no~no~no~ 上面的这一段html代码中可是有样式的,按照w3c的规范,样式应该写在css文件中,怎么实现?自然而然想到两种解决办法:
这个helper的作用就是注册一个名为”css”的helper,帮我们保存分页中用到的css文件地址。然后我们在主模板layout的head标签部分遍历cssList数组循环加载出来。
|