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