JavaScript模板引擎应用场景及实现原理解读
更新时间:2018年12月14日 10:15:57 作者:Benjamin
本文主要介绍JavaScript模板引擎的应用场景和实现原理。 结合实例详细分析了JavaScript模板引擎的具体应用场景、实现原理、相关操作方法和注意事项。 有需要的同学可以参考以下
本文通过示例介绍了JavaScript模板引擎的应用场景和实现原理。 分享给大家,供大家参考,具体如下:
1、应用场景
模板引擎可用于以下应用场景:
1.如果你有动态的ajax请求数据typescript 运用场景,需要将其封装成视图来解释给用户typescript 运用场景,你想提高你的工作效率。
2、如果你是串拼人或者字段推人,你渴望改变现有的写法。
3、如果您的页面布局中有常用的模块和布局,可以提取常用模板,减少维护次数。
2. 实现原理
不同模板的实现原理相似,各有优缺点。 请根据您的需要进行选择。 下面的例子是使用artTemplate模板引擎进行分析。
2.1 模板存储
模板通常放置在textarea/input等表单控件中,或者script[type="text/html"]等标签中,如下:
{{if isAdmin}}{{title}}
-
{{each user as name i}}
- {{i + 1}} :{{name}} {{/each}}
2.2 模板函数
通常是 templateFun("id", data); 其中id是存储模板字符串的元素id,data是需要加载的数据。
2.3 模板获取
一般是通过ID获取,document.getElementById("ID"):
//textarea或input则取value,其它情况取innerHTML var html = /^(textarea|input)$/i.test(element.nodeName) ? element.value : element.innerHTML;
2.4 模板分析——处理html语句、逻辑语句等底层处理
这一步的主要操作是解析出html元素、逻辑语句和关键字,尽管有多余的空格。 例如:artTemplate.js中的代码实现:
defaults.parser = function (code, options) { // var match = code.match(/([w$]*)(b.*)/); // var key = match[1]; // var args = match[2]; // var split = args.split(' '); // split.shift(); //if isAdmin code = code.replace(/^s/, ''); //["if", "isAdmin"] var split = code.split(' '); //if var key = split.shift(); //isAdmin var args = split.join(' '); switch (key) { case 'if': //if(isAdmin){ code = 'if(' + args + '){'; break; case 'else': if (split.shift() === 'if') { split = ' if(' + split.join(' ') + ')'; } else { split = ''; } code = '}else' + split + '{'; break; case '/if': code = '}'; break; case 'each': var object = split[0] || '$data'; var as = split[1] || 'as'; var value = split[2] || '$value'; var index = split[3] || '$index'; var param = value + ',' + index; if (as !== 'as') { object = '[]'; } code = '$each(' + object + ',function(' + param + '){'; break; case '/each': code = '});'; break; case 'echo': code = 'print(' + args + ');'; break; case 'print': case 'include': code = key + '(' + split.join(',') + ');'; break;
例如上面的例子:“{{if isAdmin}}”最终被解析为“if(isAdmin){”,“{{/if}}”被解析为“}”。
2.5 模板编译——将字符串连接成生成函数的过程
这一步的主要操作是将字符串拼接成生成函数。 看一下artTemplate的部分源码:
function compiler (source, options) { /* openTag: '', // 逻辑语法结束标签 escape: true, // 是否编码输出变量的 HTML 字符 cache: true, // 是否开启缓存(依赖 options 的 filename 字段) compress: false, // 是否压缩输出 parser: null // 自定义语法格式器 @see: template-syntax.js */ var debug = options.debug; var openTag = options.openTag; var closeTag = options.closeTag; var parser = options.parser; var compress = options.compress; var escape = options.escape; var line = 1; var uniq = {$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1}; //isNewEngin在6-8返回undefined var isNewEngine = ''.trim;// '__proto__' in {} var replaces = isNewEngine ? ["$out='';", "$out+=", ";", "$out"] : ["$out=[];", "$out.push(", ");", "$out.join('')"]; var concat = isNewEngine ? "$out+=text;return $out;" : "$out.push(text);"; var print = "function(){" + "var text=''.concat.apply('',arguments);" + concat + "}"; var include = "function(filename,data){" + "data=data||$data;" + "var text=$utils.$include(filename,data,$filename);" + concat + "}"; var headerCode = "'use strict';" + "var $utils=this,$helpers=$utils.$helpers," + (debug ? "$line=0," : ""); var mainCode = replaces[0]; var footerCode = "return new String(" + replaces[3] + ");" // html与逻辑语法分离 forEach(source.split(openTag), function (code) { code = code.split(closeTag); var $0 = code[0]; var $1 = code[1]; // code: [html] if (code.length === 1) { mainCode += html($0); // code: [logic, html] } else { mainCode += logic($0); if ($1) { mainCode += html($1); } } }); var code = headerCode + mainCode + footerCode;
上例中模板中的模板字符串代码会被拼接成如下字符串:
'use strict'; var $utils = this, $helpers = $utils.$helpers, isAdmin = $data.isAdmin, $escape = $utils.$escape, title = $data.title, $each = $utils.$each, user = $data.user, name = $data.name, i = $data.i, $out = ''; if (isAdmin) { $out += 'nn'; $out += $escape(title); $out += '
n
- n ';
$each(user, function(name, i) {
$out += 'n
- '; $out += $escape(i + 1); $out += ' :'; $out += $escape(name); $out += ' n '; }); $out += 'n
然后将生成以下函数:
var Render = new Function("$data", "$filename", code); /*Outputs: function anonymous($data, $filename) { 'use strict'; var $utils = this, $helpers = $utils.$helpers, isAdmin = $data.isAdmin, $escape = $utils.$escape, title = $data.title, $each = $utils.$each, user = $data.user, name = $data.name, i = $data.i, $out = ''; if (isAdmin) { $out += 'nn'; $out += $escape(title); $out += '
n
- n ';
$each(user, function(name, i) {
$out += 'n
- '; $out += $escape(i + 1); $out += ' :'; $out += $escape(name); $out += ' n '; }); $out += 'n
2.5 加载数据并查看演示
/*Outputs:User lists
- 1 :zuojj
- 2 :Benjamin
- 3 :John
- 4 :Rubby
- 5 :Handy
- 6 :CIMI
3. 常用JavaScript模板引擎及测试比较
artTemplate - 高性能JavaScript模板引擎(腾讯CDC)
Velocity.js - 来自天猫的 JS 模板引擎
Juicer - 高效、轻量级的 Javascript 模板引擎
Mustache.js - 使用 JavaScript 的无逻辑 {{mustache}} 模板
更多JavaScript相关内容请查看本站专题:《Javascript面向对象入门教程》、《JavaScript搜索算法技巧总结》、《JavaScript错误与调试方法总结》、《JavaScript数据结构与算法方法总结》 》、《JavaScript遍历算法与方法总结》和《JavaScript数学运算用法总结》
希望这篇文章对您的JavaScript编程设计有所帮助。