1、代码实现

var template = function template(template, data) {
    var templateSettings = Object.assign({
        escape: /<%=\s*([\s\S]+?)\s*%>/g,
        interpolate: /<%-\s*([\s\S]+?)\s*%>/g,
        evaluate: /<%\s*([\s\S]+?)\s*%>/g
    }, options || {});
    var regExp = RegExp(
        templateSettings.escape.source + '|' +
        templateSettings.interpolate.source + '|' +
        templateSettings.evaluate.source + '|([\\s\\S]+?(?=' +
        templateSettings.escape.source + '|' +
        templateSettings.interpolate.source + '|' +
        templateSettings.evaluate.source + ')|[\\s\\S]*$)|$', 'g');
    var compile = `(function (obj) {obj||(obj = {});var __t,__p='';with(obj){`
    compile += template.replace(regExp, function (match, escape, interpolate, evaluate, string) {
        if (escape) {
            return '__p+=String((__t=(' + escape + '))==null?\'\'\:__t).replace(/[&<>"\']/g, function (k) {var obj={"\\\"": "&quot;","&":"&amp;","\\\'":"&#39;","<":"&lt;",">":"&gt;"};return obj[k];});';
        } else if (interpolate) {
            return '__p+=((__t=(' + interpolate + '))==null?\'\'\:__t);';
        } else if (evaluate) {
            return evaluate;
        } else if (string) {
            return '__p+=' + JSON.stringify(string) + ';';
        }
        return '';
    });
    compile += '}return __p;})'
    return eval(compile);
};

特性

  1. 因为功能逻辑并不复杂,所以可以渲染极限的性能。

  2. 使用 JavaScript 原生语法,在复杂的业务需求都可以实现。

  3. 原始语法兼容 EJS 模板语法。

模板

<% if (user) { %>
  <h2><%= user.name %></h2>
<% } %>

使用说明

// 创建编译模板
var compiled = template('hello <%- user %>!');
compiled({ 'user': 'fred' });
// => 'hello fred!'

// 转义数据的值
var compiled = template('<b><%= value %></b>');
compiled({ 'value': '<script>' });
// => '<b>&lt;script&gt;</b>'

// 执行 JavaScript 和 生成HTML代码
var compiled = template('<% for(var i = 0; i < users.length; i++) { %><li><%= user %></li><% } %>');
compiled({ 'users': ['fred', 'barney'] });
// => '<li>fred</li><li>barney</li>'