关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JavaScript »JavaScript模板引擎的应用场景及实现原理

    JavaScript模板引擎的应用场景及实现原理

    2014-10-30 00:00:00 出处:慧都控件网
    分享

    一、应用场景

    以下应用场景可以使用模板引擎:
    1、假如你有动态ajax请求数据并需要封装成视图展现给用户,想要提高自己的工作效率。
    2、假如你是拼串族或者数组push族,迫切的希望改变现有的书写方式。
    3、假如你在页面布局中,存在共性模块和布局,你可以提取出公共模板,减少维护的数量。

    二、实现原理

    不同模板间实现原理大同小异,各有优缺,请按需选择,以下示例以artTemplate模板引擎来分析。

    2.1 模板存放

    模板一般都是放置到textarea/input等表单控件,或者script[type="text/html"]等标签中,如下:

    <script id="test" type="text/html">
    	{{if isAdmin}}
    
    	<h1>{{title}}</h1>
    	<ul>
    	    {{each user as name i}}
    	        <li> {{i + 1}} :{{name}}</li>
    	    {{/each}}
    	</ul>
    
    	{{/if}}
    </script>

    //textarea或input则取value,其它情况取innerHTML

    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: '<%',    // 逻辑语法开始标签
        closeTag: '%>',   // 逻辑语法结束标签
        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	<h1>';
    	$out += $escape(title);
    	$out += '</h1>n	<ul>n	    ';
    	$each(user, function(name, i) {
    		$out += 'n	        <li>';
    		$out += $escape(i + 1);
    		$out += ' :';
    		$out += $escape(name);
    		$out += '</li>n	    ';
    	});
    	$out += 'n	</ul>nn	';
    }
    return new String($out);

    然后会被生成如下函数:

    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	<h1>';
    		$out += $escape(title);
    		$out += '</h1>n	<ul>n	    ';
    		$each(user, function(name, i) {
    			$out += 'n	        <li>';
    			$out += $escape(i + 1);
    			$out += ' :';
    			$out += $escape(name);
    			$out += '</li>n	    ';
    		});
    		$out += 'n	</ul>nn	';
    	}
    	return new String($out);
    }
     */
    console.log(Render);

    2.5 装载数据,视图呈现

    /*Outputs:
    <h1>User lists</h1>
    <ul>
        <li>1 :zuojj</li>
        <li>2 :Benjamin</li>
        <li>3 :John</li>
        <li>4 :Rubby</li>
        <li>5 :Handy</li>
        <li>6 :CIMI</li> 
    </ul>
    */
    console.log(new Render(data, filename) + '');
    //对象转换为字符串
    return new Render(data, filename) + '';

    三、常见JavaScript模板引擎及测试对比

    BaiduTemplate —— 最简单好用的JS模板引擎(百度) artTemplate —— 高性能JavaScript模板引擎(腾讯CDC) Velocity.js —— 来自淘宝的JS 模板引擎 JavaScript Templates —— 轻量、快速、强大、无依赖模板引擎 Juicer —— 高效、轻量的Javascript模板引擎 mustache.js —— Logic-less {{mustache}} templates with JavaScript 各大Javascript模板引擎测试对比

    以上就是本文对模板引擎的描述,感谢您的阅读,文中不妥之处还望批评指正。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    小米路由器买哪款?Miwifi热门路由器型号对比分析

    IT头条

    Synology 对 Office 套件进行重大 AI 更新,增强私有云的生产力和安全性

    01:43

    StorONE 的高效平台将 Storage Guardian 数据中心占用空间减少 80%

    11:03

    年赚千亿的印度能源巨头Nayara 云服务瘫痪,被微软卡了一下脖子

    12:54

    国产6nm GPU新突破!砺算科技官宣:自研TrueGPU架构7月26日发布

    01:57

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    技术热点

    如何删除自带的不常用应用为windows 7减负

    MySQL中多表删除方法

    改进的二值图像像素标记算法及程序实现

    windows 7 32位系统下手动修改磁盘属性例如M盘修改为F盘

    windows 7中怎么样在家庭组互传文件

    Linux应用集成MySQL数据库访问技巧

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。