摘要:這是一個系列文章,將會介紹目前前端領(lǐng)域里用到的三種模板引擎技術(shù),它們分別是基于字符串的模板基于操作的模板基于虛擬的模板本文是這個系列的第一篇,著重介紹基于字符串的模板引擎的實(shí)現(xiàn)原理,分析它的優(yōu)點(diǎn)缺點(diǎn)以及使用的場景。
這是一個系列文章,將會介紹目前Web前端領(lǐng)域里用到的三種模板引擎技術(shù),它們分別是:
基于字符串的模板
基于Dom操作的模板
基于虛擬Dom的模板
本文是這個系列的第一篇,著重介紹基于字符串的模板引擎的實(shí)現(xiàn)原理,分析它的優(yōu)點(diǎn)缺點(diǎn)以及使用的場景。
進(jìn)入正文之前,我們先回顧一下在模板引擎出現(xiàn)之前,暫且稱之為“石器時代”,我們是如何利用JS改變頁面結(jié)構(gòu)的。對于下面的代碼:
我們正處于刀耕火種的石器時代
如果我們需要修改container里面的內(nèi)容,一般有2種方法:
通過JS的DOM API直接操作DOM
var newTxt = "石器時代需要自己擼工具,摩擦摩擦,似魔鬼的步伐..."; var container = document.getElementById("container"); var desc = document.createElement("H1"); var txt = document.createTextNode(newTxt); desc.appendChild(txt); container.replaceChild(desc, container.childNodes[0]);
通過innerHTML批量修改DOM結(jié)構(gòu)
var newTxt = "石器時代需要自己擼工具,摩擦摩擦,似魔鬼的步伐..."; var template = "" + newTxt + "
"; var container = document.getElementById("container"); container.innerHTML=template;
相比之下,第二種方式通過innerHTML更新DOM要簡單許多,它無需考慮DOM的層級結(jié)構(gòu),只要做簡單的字符串拼接就能實(shí)現(xiàn)需求。但這種方式的問題是代碼可讀性很差,同時開發(fā)者還必須保證最終拼接的字符串的正確性。當(dāng)需要作出修改時,面對一坨的字符也很痛苦。
在上面的例子中,我們的需求是將一個變量注入到模板當(dāng)中,類似ES6的模板字符串:
var newTxt = "石器時代需要自己擼工具,摩擦摩擦,似魔鬼的步伐..."; var template = `${newTxt}
`;
但ES6這種現(xiàn)代化的常規(guī)武器,對石器時代而言是天方夜譚。部落里的老司機(jī)憑借深厚的JS功底,擼出了各種基于字符串的模板。這些模板又可以細(xì)分為2類:一種是不包含邏輯處理,只作數(shù)據(jù)綁定用的,如mustache.js;另一種是既有邏輯處理,也有數(shù)據(jù)綁定的,如EJS。
下面,我以EJS的語法為例,實(shí)現(xiàn)一個簡單的字符串模板引擎。模版引擎的編譯流程如下:
1.首先,需要編譯模板字符串,將其轉(zhuǎn)換為JS能夠理解的語法。第一步是利用正則表達(dá)式,區(qū)分出字符串中哪些是模板語法,哪些是正常的HTML標(biāo)簽。以下是一個EJS語法的例子:
在‘<%=’和‘%>’之間是JS的表達(dá)式,而在‘<%’和’%>‘之間是普通的JS語句,可以進(jìn)行邏輯判斷和條件循環(huán)等操作。可以使用以下正則表達(dá)式抽取:
// 匹配表達(dá)式,只能有一行 let evalExpr = /<\%=(.+?)\%>/g; // 匹配語句,可以有多行 let expr = /<\%([sS]+?)\%>/g;
對于普通的HTML標(biāo)簽,需要用自定義的echo函數(shù)包裹一下,在使用eval函數(shù)編譯的時候直接輸出字符串。echo函數(shù)的定義如下:
// 臨時變量,保存編譯后的模板字符串 let output = ""; // 直接將html字符串拼接到output后面 function echo(html){ output += html; }
完整的compile函數(shù)代碼如下:
function compile(template){ // 匹配表達(dá)式,只能有一行 let evalExpr = /<\%=(.+?)\%>/g; // 匹配語句,可以有多行 let expr = /<\%([sS]+?)\%>/g; // 內(nèi)容為空的部分 let empty = /echo("");/g; template = template // 轉(zhuǎn)換JS表達(dá)式 .replace(evalExpr, "`); echo( $1 ); echo(`") // 轉(zhuǎn)換JS語句 .replace(expr, "`); $1 echo(`"); // 在模板的最外層包裹一個echo template = "echo(`" + template + "`);"; // 清除空的echo template = template .replace(empty, ""); // 保存編譯后的字符串,此處用了ES6的模板字符串特性,相當(dāng)于eval了一下 let script = `(function parse(data){ // 臨時變量,保存編譯后的模板字符串 var output = ""; // 直接將html字符串拼接到output后面 function echo(html){ output += html; } // 包含echo的模板字符串 ${ template } return output; })`; return script; }
經(jīng)過正則表達(dá)式處理后,這段代碼:
會轉(zhuǎn)化為:
echo(`
完整代碼亦可見JSFiddle
2.第二步,我們將模板中用到的數(shù)據(jù)data注入到compile函數(shù)的parse子函數(shù)中,生成最終的字符串。
3.最后,我們再通過innerHTML,把字符串插入到DOM合適的位置。
字符串模板之所以能夠更新頁面,最核心的原理是使用innerHTML這個api將字符串直接插入到DOM節(jié)點(diǎn)中。因此,我們分析字符串模板的優(yōu)缺點(diǎn)就離不開使用innerHTML更新DOM的優(yōu)缺點(diǎn)。先談?wù)剝?yōu)點(diǎn):
直觀,容易理解。更新后的DOM結(jié)構(gòu)可以一目了然的反映在字符串當(dāng)中。
容易維護(hù)。當(dāng)需要更改模板時,直接改相應(yīng)字符串就可以,新人也容易上手。
可用于服務(wù)端渲染。簡單的字符串拼接,不依賴DOM,對應(yīng)的字符串可由服務(wù)器端直接生成。
再來談?wù)勅秉c(diǎn):
安全隱患。模板字符串中完全可以出現(xiàn)此類代碼:
慢!特別對于需要頻繁更新的場景。由于innerHTML是直接替換掉原有元素,因此就涉及到相應(yīng)節(jié)點(diǎn)和對應(yīng)事件的卸載,然后再裝載新的節(jié)點(diǎn)和事件。在這個過程中,界面也會被重排和重繪,對性能是嚴(yán)重的損耗。
不智能。當(dāng)只需要修改模板里面的某一部分?jǐn)?shù)據(jù)時,整個模板頁都需要被刷新。
維護(hù)困難。這不是打臉嘛,上面才說了容易維護(hù),這里又講維護(hù)困難!?這當(dāng)然是有原因的嘛。當(dāng)不需要考慮性能的時候,一個頁面可能只需要維護(hù)一個模板,這難道不簡單?但考慮到性能的時候,就需要對模板進(jìn)行拆分和拼裝,維護(hù)這些相互依賴的模板會讓人很崩潰。
綜上所述,我們可以很簡單的總結(jié)出字符串模板引擎的使用場景:如果你的應(yīng)用比較簡單,交互也不多,也希望有一個快速的首屏?xí)r間,請使用字符串模板引擎。反之,你硬要上字符串模板引擎的話,我建議你先看看我下一期或者下下一期的文章再做決定,哈哈哈哈~
未完待續(xù)...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/84243.html
摘要:置換型模板引擎的優(yōu)點(diǎn)實(shí)現(xiàn)簡單,缺點(diǎn)效率低,無法滿足高負(fù)載的應(yīng)用請求。用途百度詞條模板引擎可以讓網(wǎng)站程序?qū)崿F(xiàn)界面與數(shù)據(jù)分離,業(yè)務(wù)代碼與邏輯代碼的分離,提升開發(fā)效率,良好的設(shè)計(jì)也提高了代碼的復(fù)用性。前端模板的出現(xiàn)使得前后端分離成為可能。 模板引擎 模板引擎-百度詞條 什么是模板引擎?(百度詞條) 模板引擎(這里特指用于Web開發(fā)的模板引擎)是為了使用戶界面與業(yè)務(wù)數(shù)據(jù)分離而產(chǎn)生的,它可以生成...
摘要:簡單來說,模板最本質(zhì)的作用是變靜為動,一切利于這方面的都是優(yōu)勢,不利于的都是劣勢。二選擇的原因全球最受歡迎的模板引擎是全球使用率最高的模板引擎,所以當(dāng)之無愧是全球最受歡迎的模板引擎。創(chuàng)建更為復(fù)雜一些,當(dāng)時功能更加強(qiáng)大。 showImg(https://segmentfault.com/img/bVbb3kg?w=775&h=216); 為什么需要使用模板引擎? 關(guān)于為什么要使用模板引擎...
摘要:歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面不僅僅是代碼作為現(xiàn)代應(yīng)用,的大量使用,使得前端工程師們?nèi)粘5拈_發(fā)少不了拼裝模板,渲染模板。我們今天就來聊聊,拼裝與渲染模板的那些事兒。一改俱改,一板兩用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog...
摘要:歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面不僅僅是代碼作為現(xiàn)代應(yīng)用,的大量使用,使得前端工程師們?nèi)粘5拈_發(fā)少不了拼裝模板,渲染模板。我們今天就來聊聊,拼裝與渲染模板的那些事兒。一改俱改,一板兩用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog...
摘要:歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面不僅僅是代碼作為現(xiàn)代應(yīng)用,的大量使用,使得前端工程師們?nèi)粘5拈_發(fā)少不了拼裝模板,渲染模板。我們今天就來聊聊,拼裝與渲染模板的那些事兒。一改俱改,一板兩用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog...
閱讀 1873·2021-11-15 11:39
閱讀 1081·2020-12-03 17:06
閱讀 737·2019-12-27 11:42
閱讀 3274·2019-08-30 13:59
閱讀 1464·2019-08-26 13:22
閱讀 3288·2019-08-26 12:15
閱讀 2475·2019-08-26 10:22
閱讀 1564·2019-08-23 18:40