现在的模板引擎挺多的,语法也多样,像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/