高性能JavaScript模板引擎template.js原理解析

简介: artTemplate是新一代javascript模板引擎,它在v8中的渲染效率可接近javascript性能极限,在chrome下渲染效率测试中分别是知名引擎Mustache与micro tmpl的25/32倍(性能测试);artTemplate的模板还支持使用自动化工具预编译; artTemplate的库分为两种,一个是template.

artTemplate是新一代javascript模板引擎,它在v8中的渲染效率可接近javascript性能极限,在chrome下渲染效率测试中分别是知名引擎Mustache与micro tmpl的25/32倍(性能测试);artTemplate的模板还支持使用自动化工具预编译;

artTemplate的库分为两种,一个是template.js(采用"{{ }}"),一个是template-native.js(采用"<%= %>");第一个是简洁语法版,第二个是原生语法(感觉像JSP)版,两个库的语法不可混用,否则会报错;本文主要是讲简洁语法

template.js是一款使用方便/性能卓越javascript模板引擎,简单/好用,支持webpack和fis,只有5K左右大小

原理

提前将Html代码放进一个<script id="test" type="text/html"></script>中,当需要用到时,在js里这样调用:var htmlstr = template("test",放Json数据或其他),然后$("#*").html(htmlstr),放进去就好

功能概述

提供一套模板语法,用户可以写一个模板区块,每次根据传入的数据,生成对应数据产生的HTML片段,渲染不同的效果

特性

1.性能卓越,执行速度通常是Mustache与tmpl的20多倍(性能测试)

2.支持运行时调试,可精确定位异常模板所在语句(演示)

3.对NodeJS Express友好支持

4.安全,默认对输出进行转义,在沙箱中运行编译后的代码(Node版本可以安全执行用户上传的模板)

5.支持include语句,可导入定义的其它模块

6.可在浏览器端实现按路径加载模板(详情)

7.支持预编译,可将模板转换成为非常精简的js文件

8.模板语句简洁,无需前缀引用数据,有简洁版本与原生语法版本可选

9.支持所有流行的浏览器

10.丰富的自定义配置

11.支持数据过滤

12.异常捕获功能

具体方法

引入template.js文件

引用简洁语法的引擎版本,例如:<script src="template.js"></script>

编写模板

使用一个type="text/html"的script标签存放模板,或者放到字符串中:

<script id="test" type="text/html">  
  {{ if ifAdmin }}  //{{}}符号包裹起来的语句为模板的逻辑表达式
    <h1>{{ author }}</h1>
    <ul>
      {{each list as value i}}
        <li>{{ i+1 }} : {{ value }}</li>
      {{/each}}
    </ul>
  {{/if}}
</script>

注意:{{}}这是都是对内容编码输出,写成{{#author}}是对内容不编码输出;编码可以防止数据中含有HTML字符串,避免引起XSS攻击

渲染模板(向模板插入数据并输出到页面)

var data = { 
  author:'宫崎骏',
  isAdmin:true,
  list:['千与千寻','哈尔的移动城堡','幽灵公主','风之谷','龙猫']
};
var html = template('test',data); //template(id,data):根据id渲染模板,内部会根据document.getElementById(id)查找模板,如果没有data参数那么将返回一渲染函数
document.getElementById('content').innerHTML = html;

输出结果

<h1>宫崎骏</h1>
<ul>
  <li>1 : 千与千寻</li>  
  <li>2 : 哈尔的移动城堡</li> 
  <li>3 : 幽灵公主</li>  
  <li>4 : 风之谷</li> 
  <li>5 : 龙猫</li> 
</ul>

语法

表达式

流程控制语句(if else)

{{if value}}
...
{{else if value}}
...
{{else}}
...
{{/if}}

示例如下

<script id="test" type="text/html">
  <div>
    {{if bok == 22}}
      <h1>线上</h1>
    {{else if bok == 33}}
      <h2>隐藏</h2>
    {{else}}
      <h3>走这里</h3>
    {{/if}}
  </div>
</script>

嵌套的写法

<script id="test" type="text/html">
  <div>
    {{if bok}}
      {{if list.length >= 0}}
        <p>线上</p>
      {{else}}
        <p>没有数据</p>
      {{/if}}
    {{/if}}
  </div>
</script>

循环遍历语句

{{each name}}
索引:{{$index}}
值:{{$value}}
{{/each}}

示例如下

<script id="test" type="text/html">
  <div>
    {{if list.length >= 0}}
      {{each list as value index}}
        <p>编号:{{index+1}} -- 姓名:{{value.name}} -- 年龄:{{value.age}}</p>
      {/each}
    {{/if}}
  </div>
</script>

也可以简写为

<script id="test" type="text/html">
  <div>
    {{if list.length >= 0}}
      {{each list}}
        <p>编号:{{$index+1}} -- 姓名:{{$value.name}} -- 年龄:{{$value.age}}</p>
      {/each}
    {{/if}}
  </div>
</script>

调用自定义方法

辅助方法

使用template.helper(name, callback)注册公用辅助方法,可以直接在{{}}中调用:

<script id="test" type="text/html">  
  <div>
    {{if c == 100}}
      <ul>
        {{each person}}
          <li>姓名:{{$value.name}} -- 性别:{{show($value.sex)}}</li>
        {{/each}}
      </ul>
    {{/if}}
  </div>
</script>
<script>
  var data = {
    c:100,
    person:[
      {name:"jack",age:18,sex:1},
      {name:"tom",age:19,sex:0},
      {name:"jerry",age:20,sex:0},
      {name:"kid",age:21,sex:1},
      {name:"jade",age:22,sex:0}
    ]
  };
  //自定义函数
  template.helper('show',function(sex){
    console.log(sex); //同样可以打印日志到控制台
    if(sex == 0){
      return "男"
    }else if(sex == 1){
      return "女"
    }
  });
  var html = template('test',data);
  document.getElementById('app').innerHTML = html;
</script>

辅助方法,可以扩展常用的公共方法

template.helper('dateFormat', function (date, format) { 
 // .. 
 return value; 
}); 

在模板中的使用方式:

语法 : {{ data | funname : '第二参数' }};

具体调用为 : funname(data,'第二参数');

模板中使用的方式:{{time | dateFormat:'yyyy-MM-dd hh:mm:ss'}}

支持传入参数与嵌套使用:{{time | say:'cd' | ubb | link}}

注意:引擎不会对辅助方法输出的HTML字符进行转义

调用子模版

{{include 'main'}}引入子模板,数据默认为共享;{{include 'main' a}},a为制定数据,但是同样必须是父级数据,可以看看下面的例子,如果不注入的a的话,引入的子模板是接受不到数据的

<body>
  <div id="app"></div>
  <script id="main" type="text/html">  
    <ul>
      {{each list}}
        <li>{{$value}}</li>
      {{/each}}
    </ul>  
    {{include 'main' a}} <!-- include--导入其它模版,很实用的一个功能 -->
  </script>
  <script type="text/html">
    <div>
      <ul>
      {{each person}}
        <li>{{$value.name}}</li>
      {{/each}}
      </ul>
      {{include 'main' a}}
    </div>
  </script>
  <script>
    var data = {
      person:[
        {name:"jack",age:18},
        {name:"tom",age:19},
        {name:"jerry",age:20},
        {name:"kid",age:21},
        {name:"jade",age:22}
      ],
      a:{
        list:['文艺','博客','摄影','电影','民谣','旅行','吉他']
      }
    };
    var html = template('test',data);
    document.getElementById('app').innerHTML = html;
  </script>
</body>

template.config

配置template.js的自定义选项

option {Object} 配置的对象参数

return {Object} 配置对象的镜像

可配置参数

字段 类型 默认值 说明
openTag string {{ 逻辑语法开始标签
closeTag string }} 逻辑语法结束标签
escape boolean true 是否编码输出HTML字符
compress boolean false 是否压缩输出的html

template.registerFunction

注册自定义函数功能

字段 类型 说明
name string 自定义函数的名字,如果缺省会返回全部已注册的函数
fn function 自定义函数,如果缺省会返回名称为name的函数
return object/function 对象或函数

template.unregisterFunction

取消自定义函数功能

字段 类型 说明
name string 取消自定义函数的名字
return bollean 是否成功

template.registerModifier

注册自定义修复器功能。

字段 类型 说明
name string 自定义修复器的名字,如果缺省会返回全部已注册的修复器
fn function 自定义修复器,如果缺省会返回名称为name的修复器
return object/function 对象或函数

template.unregisterModifier

取消自定义修复器功能。

字段 类型 说明
name string 取消自定义修饰器的名字
return bollean 是否成功

template.noConflict+

在以原始方式使用template.js时会存在改函数(在模块化开发环境中不会存在),用来释放template.js占用的全局变量template,同时会返回template

return {Function} template

模板编码规范

1.不能使用javascript关键字作为模板变量(包括 ECMA5 严格模式下新增的关键字):

break, case, catch, continue, debugger, default, delete, do, else, false, finally, for, function, if, in, instanceof, new, null, return, switch, this, throw, true, try, typeof, var, void, while, with, abstract, boolean, byte, char, class, const, double, enum, export, extends, final, float, goto, implements, import, int, interface, long, native, package, private, protected, public, short, static, super, synchronized, throws, transient, volatile, arguments, let, yield

2、模板运行在沙箱中,内部无法访问外部变量,除非给模板定义辅助方法。例如:

    template.helper('Math', Math)

模板中若任意引用外部对象,复杂的依赖管理将会让项目难以维护,这种方式将利于后续模板迁移(包括通过工具预编译)

在隔壁公司看到的:合理的要求是训练,不合理的要求是磨练

目录
相关文章
|
6天前
|
JSON 前端开发 JavaScript
【JavaScript技术专栏】JavaScript异步编程:Promise、async/await解析
【4月更文挑战第30天】JavaScript中的异步编程通过Promise和async/await来解决回调地狱问题。Promise代表可能完成或拒绝的异步操作,有pending、fulfilled和rejected三种状态。它支持链式调用和Promise.all()、Promise.race()等方法。async/await是ES8引入的语法糖,允许异步代码以同步风格编写,提高可读性和可维护性。两者结合使用能更高效地处理非阻塞操作。
|
20小时前
|
缓存 自然语言处理 JavaScript
万字长文深度解析JDK序列化原理及Fury高度兼容的极致性能实现
Fury是一个基于JIT动态编译的高性能多语言原生序列化框架,支持Java/Python/Golang/C++/JavaScript等语言,提供全自动的对象多语言/跨语言序列化能力,以及相比于别的框架最高20~200倍的性能。
|
5天前
|
JSON JavaScript 前端开发
使用JavaScript和XLSX.js将数据导出为Excel文件
使用JavaScript和XLSX.js将数据导出为Excel文件
16 0
|
6天前
|
JavaScript 前端开发 开发工具
【JavaScript 技术专栏】Node.js 基础与实战
【4月更文挑战第30天】本文介绍了Node.js的基础及应用,包括事件驱动的非阻塞I/O、单线程模型和模块系统。内容涵盖Node.js的安装配置、核心模块(如http、fs、path)及实战应用,如Web服务器、文件操作和实时通信。文章还讨论了Node.js的优劣势、与其他技术的结合,并通过案例分析展示项目实施流程。总结来说,Node.js是高效后端开发工具,适合构建高并发应用,其广阔的应用前景值得开发者探索。
|
6天前
|
JavaScript 网络协议 数据处理
Node.js中的Buffer与Stream:深入解析与使用
【4月更文挑战第30天】本文深入解析了Node.js中的Buffer和Stream。Buffer是处理原始数据的全局对象,适用于TCP流和文件I/O,其大小在V8堆外分配。创建Buffer可通过`alloc`和`from`方法,它提供了读写、切片和转换等操作。Stream是处理流式数据的抽象接口,分为可读、可写、双工和转换四种类型,常用于处理大量数据而无需一次性加载到内存。通过监听事件和调用方法,如读取文件的可读流示例,可以实现高效的数据处理。理解和掌握Buffer及Stream能提升Node.js应用的性能。
|
6天前
|
存储 芯片
【期末不挂科-单片机考前速过系列P11】(第十一章:15题速过串行口的工作原理和应用)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P11】(第十一章:15题速过串行口的工作原理和应用)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P10】(第十章:11题中断系统的工作原理及应用)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P10】(第十章:11题中断系统的工作原理及应用)经典例题盘点(带图解析)
|
7天前
|
C语言 C++
【期末不挂科-单片机考前速过系列P1】(第一章:27题搞定单片机&其工作原理)经典例题盘点【选择题&判断题&填空题】(带图解析)
【期末不挂科-单片机考前速过系列P1】(第一章:27题搞定单片机&其工作原理)经典例题盘点【选择题&判断题&填空题】(带图解析)
|
7天前
|
JavaScript 前端开发 开发者
Node.js的包管理和npm工具深度解析
【4月更文挑战第30天】本文深入解析Node.js的包管理和npm工具。包管理促进代码复用和社区协作,包包含元数据描述文件`package.json`和入口文件。npm提供搜索、安装、发布等功能,通过命令行进行操作,如`install`、`search`、`uninstall`。npm支持版本控制、全局安装、脚本定义及私有仓库。理解和熟练运用npm能提升Node.js开发效率。
|
7天前
|
JavaScript 前端开发 算法
vue生命周期函数原理解析,vue阻止事件冒泡方法实现
vue生命周期函数原理解析,vue阻止事件冒泡方法实现

推荐镜像

更多