解析字符串模板函数
关键:eval 会将传入的字符串当做js代码执行。
1..模板部分主要内容是
静态html 代码:
js代码:<% %>, if .. else..等
js表达式:<%= ...%>
2. 用正则式提取出js代码和js表达式中的内容,将这三部分合成由字符串组成的可执行函数的内容部分。
一是 根据代码和表达式增强需要输出的html
1 function compile(template){ 2 //关键是 eval 计算某个字符串并执行其中的js代码。 3 // 模板解析的时候可以将html代码部分和js代码部分合并成一个字符串,调用eval生成一个函数用于根据数据生成html代码并输出 4 //1.提取js代码<% %> js表达式<%= %> , 5 // 6 7 const codeReg =/<%=(.+?)%>/g; 8 const exprReg = /<%(.+?)%>/g; 9 10 template = template.replace(codeReg,'`)\n code($1); \n code(`') 11 .replace(exprReg,'`)\n $1 \n code(`'); 12 template='code(`'+template+'`)' 13 //连接模板内容生成一个用于生成html的函数 14 //把模板内容合成一个包含js代码和html字符串的待执行函数。 15 //导入数据并解析 16 var parse = `(function parse(data){ 17 var output=""; 18 function code(str){ 19 output+=str; 20 } 21 ${template} 22 return output; 23 })`; 24 return parse; 25 } 26 27 28 //根据模板,生成并返回一个解析函数parse 29 //parse 需要定义一个存放代码的数组,静态代码和动态代码(js)都存,然后合并后返回,只要输入数据执行此函数会自动合成html并返回 30 function compile1(template){ 31 const evalReg = /<%=(.+?)%>/g; 32 const exprReg = /<%(.+?)%>/g; 33 34 template= template.replace(evalReg,'\"); r.push($1); r.push(\"') 35 .replace(exprReg,'\"); $1 r.push(\"') 36 .replace(/[\r\n]/g,""); 37 38 template = 'r.push(\"'+template+'\");'; 39 // function parse(... 外部需要加小括号,表达式才会有返回值,不加小括号就表示声明了函数 40 var parse = '(function parse(data){' + 41 'var r = [];' + 42 template+ 43 '' + 44 '; return r.join("")' + 45 '})'; 46 return parse; 47 }
<div id="outer"> </div> <script src ="string_template.js"></script> <script> var temp1 =`<ul> <%for(var i =0;i<data.length;i++){%> <li> <% if(data[i].name=='xx'){%> <% if(data[i].name=='yy'){%> <span>上岛咖啡就是宽度</span> <%}%> <span>萨克的积分卡萨</span> <%}%> <%=data[i].name%> </li> <%}%> </ul>`; var data = [{name:"大型"},{name:"历练"},{name:"尾款"},{name:'xx'},{name:'yyy'}]; //compile1 // var parse = eval(compile(temp1)); var parse = eval(compile1(temp1)); var result=parse(data); console.log(result); document.getElementById("outer").innerHTML = result; </script>
参考:es6 标准入门