欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

简易模板引擎制作

程序员文章站 2024-01-18 19:19:40
...

什么是模板引擎?

举个例子,当我们需要渲染一段html,而这段html中包含了很多结构一样的li标签,仅仅是内容不同(内容来自渲染的数据),我们就可以把这段具有相同结构的li的html片段提取出来作为模板,需要渲染的数据用规定的语法来表示。通过一个渲染函数,将模板和需要渲染的数据作为参数传入这个函数,最终这个渲染函数返回被渲染好的html片段,然后再写入dom。

一个简单的示例

var TemplateEngine = function(tpl, data) {
    // 此处为渲染函数的代码
}
// 此处为模板,需要渲染的参数按照<%name%>的形式指定
var template = '<p>Hello, my name is <%name%>. I\'m <%age%> years old.</p>';
console.log(TemplateEngine(template, {
    name: "Krasimir",
    age: 29
}));
复制代码

以上这段函数,我们希望把传入的数据渲染到模板对应的字段,最终输出如下字符串

<p>Hello, my name is spanKrasimir. I\'m 29 years old.</p>
复制代码

抛开渲染函数函数体不谈,以上就是一个简单的模板引擎的实现原理。

实现原理

想要渲染函数实现我们的需求,第一个想的方法就是--正则表达式。在TemplateEngine 函数中,我们可以先定义一个正则表达式,用来匹配模板参数,也就是上文我们定义的<%name%>,其规则是:渲染参数被'<%'和'%>'包裹。那么我们的正则规则可以定义如下:

var re = /<%([^%>]+)?%>/g;
复制代码

这个正则的含义如下图,即匹配以'<%'和'%>'包裹且内容不包含'%'或'>'的内容

既然有了正则,我们先使用它来匹配我们的模板看下结果,这里我们使用exec方法来进行匹配,exec方法的具体用法和介绍可参考MDN 代码如下:

var re = /<%([^%>]+)?%>/g;
var match = re.exec(tpl);
复制代码

将match打印出来,得到的结果如图:

match[0]就是正则表达式匹配到的字符串,match[1]就是正则表达式匹配结果的第一个分组,分组的概念这里不多做介绍,可网上查看。但是这里我们又发现一个奇怪的地方,我的正则明明写的是全局匹配啊,按理来说这段模板字符串应该匹配到两个字符串啊,客观莫慌,接下来就介绍match.index这个属性,我们从第一次exec的结果可以看到,match.index=21,这个值就是匹配到第一个符合规则的字符串的索引位置,这可以说是exec方法的一个特性,如果我们想要匹配到后面的'<%age%>'字符串,那么我们只需要再执行一次exec方法,第二次执行会从上一次执行后的index值开始匹配,多次执行按照此规律进行,直至匹配到最后结束返回null。 为了匹配到所有的符合条件的模板字符串,我们将代码改成如下所示:

var re = /<%([^%>]+)?%>/g;
var match = '';
while(match = re.exec(tpl)){
     console.log(match)
}
复制代码

输出结果如图

到了这里,我们就能把模板中所有符合规则的字段匹配出来了,接下来要做的就是将数据用replace替换进去,我们可以在TemplateEngine中这样写:

var TemplateEngine = function(tpl, data) {
    var re = /<%([^%>]+)?%>/g, match;
    while(match = re.exec(tpl)) {
        tpl = tpl.replace(match[0], data[match[1]])
    }
    return tpl;
}
复制代码

将模板和数据传入这个函数,返回值如下:

至此,我们已经写出了一个简单的模板引擎,当传入模板和数据时,可以返回渲染后的数据。

等等,还没完,还有一部分下次整理

原文