摘要:寫在前面模板的誕生是為了將顯示與數據分離,模板技術多種多樣,但其本質是將模板文件和數據通過模板引擎生成最終的代碼。目前有著很多這種模板引擎,諸如的,,的。當然在用過這么多的模板引擎后,也有著自己實現一個簡易模板引擎的沖動。
寫在前面
模板的誕生是為了將顯示與數據分離,模板技術多種多樣,但其本質是將模板文件和數據通過模板引擎生成最終的HTML代碼。目前有著很多這種模板引擎,諸如Node的ejs,jade,PHP的Smarty。當然在用過這么多的模板引擎后,也有著自己實現一個簡易模板引擎的沖動。于是今天就實現了一個簡單的模板引擎,這個模板引擎非常簡單,并不會涉及到語法分析,詞法分析等編譯原理相關知識,做的僅僅是將模板的js代碼執行。下面來和大家分享下:
實現模板引擎語法參照的是ejs:
<% js code %>
<%= 變量名 %>
看下需要實現的目標:
// 模板代碼
下面來考慮下,其實形成上述的html的話,利用js拼接字符串就可以做到,那么對于模板來說,是不是可以將模板內的js代碼轉化為原生js代碼從而來實現呢?沒錯,這個簡單的模板引擎干的就是這個事情,就是將模板內的被<% %>包裹的js代碼執行,從而將模板轉為html。
但是,如何做呢?可以采用Function(參數名, 函數主體),雖說這個平時不怎么使用,但是在這個情況下是最好的選擇,將模板內的js代碼解析提取后當做參數傳入到Function中:
/** * 將模板引擎轉化為可用dom字符串 * * @param {String} tpl * @param {Object} data 數據對象,為鍵值對形式,鍵值為數據名 * @return {String} */ function tpl2dom (tpl, data) { var nbspRE = /s{2,}/g, quotRE = /"/g, main = ""; // 函數主體 function fn (d) { var i, keys = [], vals = []; for (i in d) { keys.push(i); // 參數名 vals.push(d[i]); // 參數對應的值 } return (new Function(keys, main)).apply(d, vals); } if (!main) { tpl = tpl.replace(//g, ">"); // 將<和>替換 var tpls = tpl.split("<%"), len = tpls.length; main = `var res = "${tpls[0].replace(nbspRE, "").replace(quotRE, """)}"; `; // res就是拼接的html字符串 for (var i = 1; i < len; i++) { var p = tpls[i].split("%>"); // 發現第一個字符為`=`號時,直接進行賦值操作 main += 0x3D === p[0].charCodeAt(0) ? ` res += ${p[0].substr(1)}`: ` ${p[0].replace(/ /g, "").trim()}`; main += ` res += "${p[p.length - 1] .replace(nbspRE, "") .replace(quotRE, """) .replace(/[ ]/g, "")}"`; } main += " return res;"; } return data ? fn(data) : fn(); }
利用tpl2dom函數可以得到html,那下面在寫一個函數來將html轉為dom節點。從下面的函數可以看出的就是,這個模板引擎所解析的模板,只能有一個dom根節點:
var cacheDiv = document.createElement("div"); /** * 將可用dom字符串轉為dom節點 * * @param {String} str * @return {DOM} */ function str2dom (str) { cacheDiv.innerHTML = ""; cacheDiv.innerHTML = str; // 由此可看出,模板只能有一個根節點 return cacheDiv.childNodes[0]; }
到此為止,模板引擎就基本完成了,既然是仿照的ejs,那么在來完善下,比如img_tag:
// 注意,實現該函數需放到全局 function img_tag (url) { return `` }
完整代碼請見github,當然這個模板引擎只是一個玩物,并不能用于生產,比如,根本沒有考慮到渲染過程中出錯時如何定位到具體位置等問題。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/80498.html
摘要:整個引擎實現只有不到行代碼。不知道你有木有聽說過一個基于的頁面預處理器,叫做。最初我只是打算寫一個的預處理器,不過后來擴展到了和,可以用來把代碼轉成和代碼。最后一個改進可以使我們的模板引擎更為強大。 導讀:AbsurdJS 作者寫的一篇教程,一步步教你怎樣用 Javascript 實現一個純客戶端的模板引擎。整個引擎實現只有不到 20 行代碼。如果你能從頭看到尾的話,還能有不少收獲的。...
摘要:暫時沒有指令和。當前模塊內的組件可以使用來自根模塊和當前模塊的任何服務及組件,也可以使用被導入模塊中導出的組件。作為一個前端菜雞,還是在深知自己眾多不足以及明白好記性不如爛筆頭的道理下,多造輪子總歸不會錯的。 有個同事跟我說:需求還是不夠多,都有時間造輪子了。。。 前言 這個輪子從18年4月22造到18年10月12日,本來就是看了一個文章講前端框架的路由實現原理之后,想試著擼一個路由試...
摘要:要求不需要有控制流成分如循環條件等等,只要有變量替換功能即可級聯的變量也可以展開被轉義的的分隔符和不應該被渲染,分隔符與變量之間允許有空白字符例子,實現先寫下函數的框架顯然,要做的第一件事便是匹配模板中的占位符。 首發于我的博客 轉載請注明出處 這是源于兩年前,當我在做人生中第一個真正意義上的網站時遇到的一個問題 該網站采用前后端分離的方式,由后端的 REST 接口返回 JSON 數據...
摘要:模板通常用來定義顯示的形式,能夠使得數據展現更為豐富,而且容易維護。從模板引擎的實現上看,需要依賴編程語言的動態編譯或者動態解釋的特性,以簡化實現和提高性能。本文就來實現一個簡易的模板引擎,以展現的強大之處。 模板簡介 模板通常是指嵌入了某種動態編程語言代碼的文本,數據和模板通過某種形式的結合,可以變化出不同的結果。模板通常用來定義顯示的形式,能夠使得數據展現更為豐富,而且容易維護。...
閱讀 1084·2021-10-08 10:04
閱讀 3523·2021-08-05 10:01
閱讀 2278·2019-08-30 11:04
閱讀 1794·2019-08-29 15:29
閱讀 836·2019-08-29 15:12
閱讀 1670·2019-08-26 12:11
閱讀 3115·2019-08-26 11:33
閱讀 1163·2019-08-26 10:23