模板引擎 javascript --汪腾腾

前言

看到模板引擎,想到的就是字符串处理,正则匹配,下面正式开始处理字符串。

1. 简写版模板引擎

var str = "Hello, <%name%>";
var data = {name: 'ember'};

var result = str.replace(/<%([^%>]+)?%>/g, function(s0, s1){
     return data[s1];
});

 结果很理想,就是hello,ember 。当然我们写代码不可能需要这么简单的模板引擎。肯定是更复杂的需求。

var data = {
     name: "ember",
     userInfo: {age: 23}
};

 这时候你就想打人了,对象中嵌套对象。不要慌,总有解决办法的。。。。

2. 嵌套对象版

var str = 'Hello, <%name%>,我<%info.age%>岁啦';
var data = {
     name: 'ember',
     info: {age: 23}
};

var result = str.replace(/<%([^%>]+)?%>/g, function(){
          var key = arguments[1];
           return "' +data." + key + "+ '";
});

 result = "return '" + result + "'";

 var newFn = new Function(result).apply(data);

 首先我们先需要把字符串变成这个样子  'Hello, ' + data.name+ ',我' + data.info.age+ '岁啦' 

 用arguments[1] 获取正则匹配成功的结果,然后把这些结果返回出去

 然后需要把这些字符串连接起来

 最后一步很关键,构造一个新的函数,这样就可以执行我们的字符串中的js逻辑代码了!!!

var newFn = new Function(result).apply(data);

new Function 后的apply(data)主要是为了绑定构建函数时, result的作用域,防止出现错误。。。或者写成下面的格式也可以

var newFn = new Function('data',result);

但是执行函数时,必须在newFn(data),里加上data。

封装一下,毕竟我们是精致的宝宝^_^

var str = 'Hello, <%name%>,我<%info.age%>岁啦';
var data = {
      name: 'ember',
      info: {age: 23}
};
var template = function(str,data) {
      var result = str.replace(/<%([^%>]+)?%>/g, function(){
      var key = arguments[1];
            return "' +data." + key + "+ '";
      });

       result = "return '" + result + "'";

       return  new Function(result).apply(data);
 }
template(str,data);

3. 高级版,可以解决模板引擎中嵌入js语句

var str = `
    Hello, <%name%>,我<%info.age%>岁啦.
    <%if(data.info.age == 23){%>
           我是真的23了。
    <%}%>`

字符串中的js逻辑代码是要单独拿出来,不能放在字符串中,不然没办法执行。

最终代码如下:

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

  //   
var add = function (line, js) { js ? (code += line.match(regOut) ? line + '\n' : 'r.push(' + line + ');\n') : (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : ''); return add;   }
  //切分字符串   
while (match = reg.exec(tpl)) { add(tpl.slice(cursor, match.index))(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); };

 

猜你喜欢

转载自www.cnblogs.com/teteWang-Ember/p/9726038.html