成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

自己動(dòng)手?jǐn)]個(gè)簡(jiǎn)易模板引擎(50行左右)

ixlei / 1529人閱讀

摘要:寫在前面模板的誕生是為了將顯示與數(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):

// 模板代碼
    <% for (var i = 0; i < 5; i++) { %> <% if (i === 0) { %>
  • <%= i %>
  • <% } else { %>
  • <%= (i + 11) %>
  • <% } %> <% } %> /ul> // 轉(zhuǎn)化為html后
    • 0
    • 12
    • 13
    • 14
    • 15

下面來(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

相關(guān)文章

  • 只有20Javascript代碼!手把手教你寫一個(gè)頁(yè)面模板引擎

    摘要:整個(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 行代碼。如果你能從頭看到尾的話,還能有不少收獲的。...

    Luosunce 評(píng)論0 收藏0
  • 用typescript擼個(gè)前端框架InDiv

    摘要:暫時(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è)路由試...

    liangzai_cool 評(píng)論0 收藏0
  • 17 代碼實(shí)現(xiàn)的簡(jiǎn)易 Javascript 字符串模板

    摘要:要求不需要有控制流成分如循環(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ù)...

    yacheng 評(píng)論0 收藏0
  • javascript模板引擎和實(shí)現(xiàn)原理

    摘要:模板通常用來(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ù)。...

    Shihira 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<