首页 > 代码库 > 【仿doT前端模板】一、最简单的值替换
【仿doT前端模板】一、最简单的值替换
想达到什么效果?
首先,我们先来看看doT中是怎样一个效果
标记变量的格式为 {{= }}
我们输出结果的容器为: <div id="output"></div>
模板:
1 <script id="template" type="text/x-dot-template"> 2 <p>Hi {{=it.name}}!</p> 3 </script>
调用方式:
1 var data = http://www.mamicode.com/{name:"十一川"}; 2 var tempFun = createTemplate($("#template").html()); 3 $("#output").html(tempFun(data));
这样当我们在外部将生成的函数保存下来之后,我们就可以通过传入不同的数据data
来生成不同的文本,比如,当我们这样tempFun({name:"十一川"})
我们得到就是<p>Hi 十一川!</p>
那么,我们又如何来生成这个函数呢?
思路·如何实现?
通过观察,我们不难发现,tempFun
这个函数所要做的,无非是每次都将模板文本中{{= }}
包裹起来的文本替换成具体的变量名,而没有被{{= }}
包裹的部分,我们则转换成字符串保持原样输出。最后将结果按照顺序拼接起来。于是,我们便将这个难题转化成数个小任务:
- 外部函数 根据模板文本生成 模板函数
- 匹配出
{{= }}
标记 - 将标记中的文本转换成外部某个变量的具体值
任务·基本结构
首先,我们定义一个createTemplate
函数,这个函数根据传入的模板文本text
生成并返回一个函数(即内部变量templateFunction
)。看起来大概是这样:
1 var createTemplate = function(text) { 2 var templateFunction = function(data) { 3 return html; 4 } 5 return templateFunction; 6 }
任务·找出变量名
接下来我们要实现的,是这么一个转换:
也就是说,我们要匹配的东西有3个:{{=
,中间的变量名
,}}
,其他的统统当成文本处理。
因为{{= }}
这个标记左右两半部分都是很固定的,因此使用正则表达式可以很自然地实现这个效果,由于{
、}
和=
在正则中都是关键字,因此我们在正则表达式中要通过转义字符\{
、\}
和\=
来分别表示这三个字符。而匹配任意字符,则可以使用.*
,至此,我们的正则表达式已经跃然纸上: var VALUE = http://www.mamicode.com/{/{/=(.*?)\}\}/g;
我们已经成功地将变量名揪出,那么,我们只要将匹配到的表达式左右都当成文本,中间换成值就行了,回想一下,我们以前是怎么写这样的代码的?是不是"text" + value + "text"
?那么我们的代码又是呼之欲出了:text.replace(VALUE, "‘+$1+‘");
任务·变量名 => 具体值
那么,在我们成功的转化为文本+变量的形式之后,生成的函数templateFunction
又要如何将完成这个 变量名 => 变量值 的转换过程呢?没错!正是eval
函数。有人会觉得使用这个函数会有些性能问题,但是没关系,因为我们这个是第一版嘛,先把功能实现再去考虑后续的优化。
完整实现
1 var VALUE = http://www.mamicode.com/{/{=(.*)/}/}/g; 2 3 function(function) { 4 function templateFunction(it) { 5 var result = templateText.replace(VALUE, "‘+$1+‘"); 6 var ev = "‘" + result.split(‘\n‘).join("‘\n+‘") + "‘"; 7 var html = eval(ev); 8 return html; 9 } 10 return templateFunction; 11 }
怎么样,是不是简单得令人吃惊呢?
其他问题
为何要使用单引号而不是双引号来包裹字符串?
通过刚刚的代码,我们不难发现,我们只是简单的通过拼接字符串来实现这个模板引擎的,要使用单引号或者双引号将文本包裹起来以生成字符串,而如果在模板文本中含有单引号或者双引号,会导致字符串提前结束而报错。考虑到html中包裹属性的基本是双引号,所以我们使用了出现频率较低的单引号。当然,这个是个可以修复的bug,不过我们就稍微偷懒一下,留到以后的版本修复吧:)
相关知识扩展
正则表达式
js中的正则表达式
eval 函数
doT模板引擎
【仿doT前端模板】一、最简单的值替换