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