简单实现模版引擎

现在的模板引擎挺多的,语法也多样,像handlerbar.js, template.js, artTemplate等等,模板引擎流程如下:

模板 -> 输入到模板引擎 -> 生成函数 -> 把数据当成参数,执行该函数 -> 输出结果

简单的模板引擎实现原理基本是用正则匹配的,复杂点的可能会用AST。

以下是两个简单实现template引擎的例子:
template1: https://juejin.im/post/59663eaa6fb9a06ba73d4c35

// Template1
var tmpl = function(tpl, data) {
    var re = /<%([^%>]+)?%>/g;
    var reExp = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g;
    var match;
    var cursor = 0;
    code = 'var r=[];\n';

    var add = function(line, js) {
        js? code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n':
        code += 'r.push("' + line.replace(/"/g, '\\"') + '");\n';
    }

    while(match = re.exec(tpl)) {
        add(tpl.slice(cursor, match.index));
        add(match[1], true);
        cursor = match.index + match[0].length;
    }
    add(tpl.substr(cursor, tpl.length - cursor));
    code += 'return r.join("");';

   // console.log(code);

    return new Function(code.replace(/[\r\t\n]/g, '')).apply(data);
}

使用:

var template1 = '<p>Hello, my name is <%this.name%>. I\'m <%this.profile.age%> years old.</p>';
var tpl1 = tmpl(template1, {
    name: "Krasimir",
    profile: {age: 29}
})

template2: https://johnresig.com/blog/javascript-micro-templating/

// Template2
(function() {
    var cache = {};

    this.tmpl = function tmpl(str, data) {
        var fn = !/\W/.test(str) //字母数字下划线
            ? cache[str] = cache[str] || tmpl(document.getElementById(str).innerHTML)
            : new Function(
                "obj",
                "var p = [], print = function() {p.push.apply(p, arguments);};"
                + "with(obj){p.push('"
                + str.replace(/[\r\t\n]/g, " ")
                    .split("<%").join("\t")
                    .replace(/((^|%>)[^\t]*)'/g, "$1\r")
                    .replace(/\t=(.*?)%>/g, "',$1,'")
                    .split("\t").join("');")
                    .split("%>").join("p.push('")
                    .split("\r").join("\\'")
                + "');}return p.join('');");

                return data ? fn(data) : fn;
    };
})();

use:

var tpl = (
  ` <div id= "item_tmpl">
         <div id="<%=id%>" class="<%=(i % 2 == 1 ? 'even' : '')%>">
             <div class="grid_1 alpha right">
             <img class="righted" src="<%=profile_image_url%>"/>
             </div>
         </div>
         <%for ( var i = 0; i < users.length; i++ ) { %>
             <li><a href="<%=users[i].url%>"><%=users[i].name%></a></li>
           <% }%>
     </div>`
);

var dataObject = {
    users: [{
        url: 'https://baidu.com',
        name: '百度'
    }, {
        url: 'https://google.com',
        name: '谷歌'
    }],
    id: 1,
    i: 6,
    profile_image_url: 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png'
};

var div2 = document.createElement('div');
div2.innerHTML = tmpl(tpl, dataObject);
document.body.appendChild(div2);

Others:
http://www.alloyteam.com/2016/10/implement-a-simple-template-engine/
https://handlebarsjs.com/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值