模板引擎,就是在定義好的模板上面填充與其對應的數(shù)據(jù)生成靜態(tài)的html頁面,即:
模板 + 數(shù)據(jù) =====> html頁面
模板引擎的作用是抽象公共頁面來重用,并且達到【視圖(包括展示渲染邏輯)與程序邏輯的分離】(mvvc,mvc等開發(fā)模式思想)
目前用過的類似模板引擎有JSP、freemarker,這兩種都屬于java范疇的,服務端解析。而作為前端的模板引擎,Handlebars脫穎而出,為前后端分離提供了方案。Handlebars是JavaScript 的一個語義模板庫,通過對view和data的分離來快速構(gòu)建Web模板。它在加載時被預編譯,而不是到了客戶端執(zhí)行到代碼時再去編譯, 這樣可以保證模板加載和運行的速度。
在了解模板引擎前,在加載一個新聞列表時,如下:

假設這個列表需要填充的數(shù)據(jù)是以下json數(shù)組:
var JSON_DATA = [
{
"title" : "德國iPhone禁售令的最新相關信息",
"date" : "2018-12-21",
"tag" : "今日熱點"
},
{
"title" : "RNG戰(zhàn)勝EDG的最新相關信息RNG戰(zhàn)勝EDG是怎么回事",
"date" : "2018-12-20",
"tag" : "電競熱點"
},
{
"title" : "德國iPhone禁售令的最新相關信息",
"date" : "2018-12-21",
"tag" : "今日熱點"
},
{
"title" : "RNG戰(zhàn)勝EDG的最新相關信息RNG戰(zhàn)勝EDG是怎么回事",
"date" : "2018-12-20",
"tag" : "電競熱點"
}
];
我們可能會這樣寫:
<div class="news-list">
<h4>新聞列表</h4>
<ul id="newsList"></ul>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script>
var html = "";
for(var i in JSON_DATA){
html += '<li class="flex"><div class="left"><span></span></div><div class="right">';
html += '<h4>'+JSON_DATA[i].title+'</h4><div class="flex"><span>'+JSON_DATA[i].tag+'</span><span>'+JSON_DATA[i].date+'</span>';
html += '</div></div></li>';
}
$("#newsList").html(html);
</script>
這樣寫也實現(xiàn)了填充數(shù)據(jù)并生成靜態(tài)html,但是缺點也很明顯;
1.代碼不清晰,比較混亂,可讀性差
2.拓展性不強,如果需要填充的內(nèi)容數(shù)據(jù)類型不夠直觀、需要轉(zhuǎn)換,這種寫法轉(zhuǎn)換起來比較麻煩
3.假設頁面布局結(jié)構(gòu)變動,那么邏輯代碼維護起來麻煩
與之對比起來,Handlebars的優(yōu)點就顯而易見了
1:Handlebars使用起來方便簡潔,可快速創(chuàng)建模板;
2:擴展性強,可根據(jù)自己的需要自定義Helpers,例如常見的類型轉(zhuǎn)換、時間格式轉(zhuǎn)換等;
3:視圖與邏輯分離,解耦性強;
4:被廣泛推廣,輕量級、兼容性強;
下面使用Handlebars來完成上面示例數(shù)據(jù)的填充:
1.在頁面中引入Handlebars資源
<script type="text/javascript" src="http://cdn.bootcss.com/handlebars.js/4.0.6/handlebars.js"></script>
2.使用<script>標簽創(chuàng)建模板,id命名是為了后面進行編譯的時候找到該模板。{{value}}嵌入變量,示例中使用了json數(shù)組的title、tag、date字段,實際情況根據(jù)自己所需要的字段填充
<script type="text/template" id="newsListTemplate">
<!--each遍歷json數(shù)組-->
{{#each this}}
<li class="flex">
<div class="left">
<span></span>
</div>
<div class="right">
<h4>{{title}}</h4>
<div class="flex">
<span>{{tag}}</span>
<span>{{date}}</span>
</div>
</div>
</li>
{{/each}}
</script>
3.使用Handlebars.compile編譯模板
//通過模板定義的id獲取模板
var tpl = $("#newsListTemplate").html();
//預編譯模板
var template = Handlebars.compile(tpl);
//傳入需要填充的數(shù)據(jù)匹配
var html = template(JSON_DATA);
//插入模板到ul中
$("#newsList").html(html);
示例完整代碼:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
<title>Handlebar新聞列表示例</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.news-list > h4 {
padding: .3rem .2rem;
font-size: .32rem;
border-bottom: 1px solid #d2d2d2;
}
.news-list ul li{
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
margin-left: .2rem;
padding: .45rem .3rem .45rem 0;
border-bottom: 1px solid #d2d2d2;
font-size: .3rem;
color: #4e4e4e;
}
.news-list ul li .left{
margin-right: .4rem;
}
.news-list ul li .left span{
display: block;
width: 1.8rem;
height: 1.2rem;
background-color: #d2d2d2;
}
.news-list ul li .right{
width: 100%;
}
.news-list ul li .right h4{
font-weight: normal;
margin-top: -.1rem;
margin-bottom: .12rem;
}
.news-list ul li .right div{
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
justify-content: space-between;
}
.news-list ul li .right div span{
display: inline-block;
font-size: .24rem;
}
.news-list ul li .right div span:first-of-type{
padding: .02rem .04rem;
background-color: #4a6efc;
color: #fff;
}
</style>
<script>
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if(clientWidth>=640){
docEl.style.fontSize = '85px';
}else{
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
}
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
</head>
<body>
<div class="news-list">
<h4>新聞列表</h4>
<ul id="newsList"></ul>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="http://cdn.bootcss.com/handlebars.js/4.0.6/handlebars.js"></script>
<script type="text/template" id="newsListTemplate">
<!--each遍歷json數(shù)組-->
{{#each this}}
<li class="flex">
<div class="left">
<span></span>
</div>
<div class="right">
<h4>{{title}}</h4>
<div class="flex">
<span>{{tag}}</span>
<span>{{date}}</span>
</div>
</div>
</li>
{{/each}}
</script>
<script>
var JSON_DATA =
[
{
"title" : "德國iPhone禁售令的最新相關信息",
"date" : "2018-12-21",
"tag" : "今日熱點"
},
{
"title" : "RNG戰(zhàn)勝EDG的最新相關信息RNG戰(zhàn)勝EDG是怎么回事",
"date" : "2018-12-20",
"tag" : "電競熱點"
},
{
"title" : "德國iPhone禁售令的最新相關信息",
"date" : "2018-12-21",
"tag" : "今日熱點"
},
{
"title" : "RNG戰(zhàn)勝EDG的最新相關信息RNG戰(zhàn)勝EDG是怎么回事",
"date" : "2018-12-20",
"tag" : "電競熱點"
}
]
;
//通過模板定義的id獲取模板
var tpl = $("#newsListTemplate").html();
//預編譯模板
var template = Handlebars.compile(tpl);
//傳入需要填充的數(shù)據(jù)匹配
var html = template(JSON_DATA);
//插入模板到ul中
$("#newsList").html(html);
</script>
</body>
</html>
官方下載地址:http://handlebarsjs.com/
參考文章:https://www.cnblogs.com/yldf55/p/5147996.html
原文作者技術博客:http://www.itdecent.cn/u/ac4daaeecdfe
95后前端妹子一枚,愛閱讀,愛交友,將工作中遇到的問題記錄在這里,希望給每一個看到的你能帶來一點幫助。
歡迎留言交流。