本身着手撸个浅易模板引擎(50行摆布)

写在前面

模板的降生是为了将显现与数据星散,模板手艺多种多样,但其本质是将模板文件和数据经由过程模板引擎天生终究的HTML代码。现在有着许多这类模板引擎,诸如Node的ejsjade,PHP的Smarty。固然在用过这么多的模板引擎后,也有着本身完成一个浅易模板引擎的激动。因而本日就完成了一个简朴的模板引擎,这个模板引擎异常简朴,并不会涉及到语法剖析,词法剖析等编译道理相干学问,做的仅仅是将模板的js代码实行。下面来和人人分享下:

完成模板引擎

语法参照的是ejs

  • <% js code %>

  • <%= 变量名 %>

看下须要完成的目的:

// 模板代码
<ul>
    <% for (var i = 0; i < 5; i++) { %>
        <% if (i === 0) { %>
            <li><%= i %></li>
        <% } else { %>
            <li><%= (i + 11) %></li>
        <% } %>
    <% } %>
/ul>
// 转化为html后
<ul>
    <li>0</li>
    <li>12</li>
    <li>13</li>
    <li>14</li>
    <li>15</li>
</ul>

下面来斟酌下,实在构成上述的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(/&lt;/g, '<').replace(/&gt;/g, '>'); // 将&lt;和&gt;替代
        var tpls = tpl.split("<%"),
            len = tpls.length;
        main = `var res = "${tpls[0].replace(nbspRE, '').replace(quotRE, "\'")}";\n`;  
        // res就是拼接的html字符串
        for (var i = 1; i < len; i++) {
            var p = tpls[i].split("%>");
            // 发明第一个字符为`=`号时,直接进行赋值操纵
            main += 0x3D === p[0].charCodeAt(0) ? 
                            `\nres += ${p[0].substr(1)}`: 
                            `\n${p[0].replace(/\r\n/g, "").trim()}`;         
            main += `\nres += "${p[p.length - 1]
                            .replace(nbspRE, '')
                            .replace(quotRE, "\'")
                            .replace(/[\r\n]/g, '')}"`;
        }
        main += "\nreturn 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 `<img src="${url}" />`
}

完全代码请见github,固然这个模板引擎只是一个玩物,并不能用于临盆,比方,基础没有斟酌到衬着过程当中失足时怎样定位到具体位置等题目。

    原文作者:zp1996
    原文地址: https://segmentfault.com/a/1190000007013591
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞