art-template-经验.txt

官网：https://aui.github.io/art-template/
开源位置：https://github.com/aui/art-template UseBy:6,149 ⏱:530 ⭐️:9.2k Fork: 2.7k
npm https://www.npmjs.com/package/art-template Weekly Downloads 42,051
art-template@4 新特性一览 https://github.com/aui/art-template/issues/369
中文网：https://aui.github.io/art-template/zh-cn/
文档：https://aui.github.io/art-template/zh-cn/docs/
英文文档：https://aui.github.io/art-template/docs/

在线测试、演示：
https://codepen.io/openmis/pen/ZEOdjZg

1、介绍
	1）支持压缩页面
压缩页面 https://aui.github.io/art-template/zh-cn/docs/minimize.html
		1> art-template 内建的压缩器可以压缩 HTML、JS、CSS，它在编译阶段运行，因此完全不影响渲染速度，并且能够加快网络传输。
		2> template.defaults.minimize = true;
	2）有腾讯开发的

2、资料
腾讯art-template4，即vue后又获一利器 https://blog.csdn.net/achenyuan/article/details/76959918
art-template4.0使用 https://my.oschina.net/shuaihong/blog/2056422

Vue-ArtTemplate-jQuery 一起使用 https://qtdebug.com/fe-vue-arttemplate/

轻量级artTemplate引擎 实现前后端分离—语法篇（实战） http://www.imooc.com/article/20293
轻量级artTemplate引擎 实现前后端分离—基础篇（实战） http://www.imooc.com/article/20263
轻量级artTemplate引擎 实现前后端分离—应用实战篇（实战） http://www.imooc.com/article/20334

3、在服务端使用art-template
在浏览器和node服务器中使用art-template模板引擎 https://www.cnblogs.com/chuanzi/p/10512516.html
在浏览器和服务端使用art-template模板引擎 https://blog.csdn.net/line233/article/details/89519636
17 —— 服务端渲染 —— art-template https://www.cnblogs.com/500m/p/10956508.html
高性能前端 art-template 模板 https://www.cnblogs.com/fly_dragon/p/9186703.html

4、art的VS Code扩展
Art Template Helper https://marketplace.visualstudio.com/items?itemName=ZihanLi.at-helper
k-url https://marketplace.visualstudio.com/items?itemName=shangguorui.k-url

5、【已知问题】
	1）扩展名.art在VS Code的代码自动提示没有html好，建议使用.art.html为模板的扩展名
	2）包含或者layout的extend如果使用相对路径，必须在前面加./或者../，
	否则在node环境是基于磁盘根目录，非webpack的htmlWebpackPlugin环境是基于项目根目录。
	3）使用JavaScript函数需要单独导入，不能像yaya-template那样直接可以使用。

6、包含子模板
示例：https://github.com/aui/art-template/blob/master/example/node-include/index.art
	1）使用
方式一：仅使用主模板里的数据
{{include './footer.art'}}

方式二：可以使用主模板里的数据，也支持额外的数据
<%
   include('./header.art', {
      title: title
   })
%>
	2）路径前面必须./开头，否则被视为相对于磁盘根目录。
	
7、layout母版
	1）可以使用模板里的数据
	2）layout母版可以继承其他layout母版

8、教程
js模板引擎-art-template常用总结 https://blog.csdn.net/orichisonic/article/details/84783728

9、模板支持
	1）模板里支持javascript

10、layout母版或包含子模板，可以使用单引号，也可以使用双引号，官方一般使用单引号。
	
11、相关cdn
https://cdnjs.com/libraries/art-template 【版本最新】
https://www.bootcdn.cn/art-template/
http://www.staticfile.org/ 搜索art-template
	1）在浏览器中实时编译 下载：template-web.js（gzip: 6kb）
【官方文档】https://aui.github.io/art-template/zh-cn/docs/installation.html#%E5%9C%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E4%B8%AD%E5%AE%9E%E6%97%B6%E7%BC%96%E8%AF%91

12、在浏览器中实现
	1）在浏览器中实时编译 下载：template-web.js（gzip: 6kb）
【官方文档】https://aui.github.io/art-template/zh-cn/docs/installation.html#%E5%9C%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E4%B8%AD%E5%AE%9E%E6%97%B6%E7%BC%96%E8%AF%91

兼容 IE8+（IE8 需要补丁才能运行。示例）
差异
因为浏览器不支持文件系统，所以 template(filename, data) 不支持传入文件路径，它内部使用 document.getElementById(filename).innerHTML 来获取模板，例如：
<script src="lib/template-web.js"></script>
<script id="tpl-user" type="text/html">
{{if user}}
  <h2>{{user.name}}</h2>
{{/if}}
</script>
	2）资料
art-template模版引擎，如何使用前端浏览器实时编译？ https://newsn.net/say/art-template-web.html
art-template（浏览器安装版&标准语法） https://blog.csdn.net/MiemieWan/article/details/80613138
	3）模板默认不支持从url里加载，可以自己编写支持：使用ajax从服务端url获取模板的html，
	设置指定<script id="tpl-user" type="text/html">的innerHTML值，然后把这个script的id字符串传给template方法。

13、webpack使用art-template
webpack使用art-template https://blog.csdn.net/jx950915/article/details/88286350
webpack + art-template的基本配置、用法 https://blog.csdn.net/xiaoyao9524/article/details/80482571
	1）art-template-loader
开源位置：https://github.com/aui/art-template-loader ⏱:3 ⭐️:95 Fork:29

14、过滤器，使用此功能来间接调用注入的函数
【官方问题】过滤器 https://aui.github.io/art-template/zh-cn/docs/syntax.html#%E8%BF%87%E6%BB%A4%E5%99%A8
	1）调用方法：(|符号前后空格不可省略)
{{参数1 | 方法名:参数2,参数3,...,参数n}}

【已知问题】
	1）使用JavaScript函数需要单独导入，不能像yaya-template那样直接可以使用。

15、除过滤器外，另外一种在模板里使用JavaScript函数的方法：在模板数据里定义一个属性，值为箭头函数的方式
	1）在线测试
https://codepen.io/openmis/pen/eYzwLmm
	2）主要代码
var render = template.compile(document.getElementById("tpl-test").innerHTML);
var html = render({fun1:(a,b)=>a+b, fun2:()=>new Date(),fun3:()=>new Date().toString(),fun4:function(){return "hello"}});
document.getElementById("result").innerHTML = html

//模板
<script id="tpl-test" type="text/html">
<div>{{fun1(1,2)}}<div>
<div>{{fun2()}}<div>
<div>{{fun3()}}<div>
<div>{{fun4()}}<div>
</script> 

//输出结果
3
"2020-11-21T23:30:11.975Z"
Sun Nov 22 2020 07:30:11 GMT+0800 (中国标准时间)
hello

16、在模板里设置data的附加值或修改原来属性值
	1）已知情况
新的属性：
{{set data.newProperty = 12345 }} //【错误】模板编译错误
{{set $data.newProperty = 12345 }} //【错误】模板编译错误
{{data.newProperty = 12345 }} //【错误】ERROR in Template execution failed: TypeError: Cannot set property 'newProperty' of undefined
{{$data.newProperty = 12345 }} //【正确，并且会输出12345】
{{$data["newProperty"] = 12345 }} //【正确，并且会输出12345】

<% set data.newProperty = 12345 %> //【错误】模板编译错误
<% set $data.newProperty = 12345 %> //【错误】模板编译错误
<% data.newProperty = 12345 %> //【错误】ERROR in Template execution failed: TypeError: Cannot set property 'newProperty' of undefined
<% $data.newProperty = 12345 %>//【正确，不会输出结果】
<% $data["newProperty"] = 12345 %>//【正确，不会输出结果】
<%= $data.newProperty = 12345 %>//【正确，并且会输出12345】
<%= $data["newProperty"] = 12345 %>//【正确，并且会输出12345】

已有的属性：
{{set data.oldProperty = 12345 }} //【错误】模板编译错误
{{set $data.oldProperty = 12345 }} //【错误】模板编译错误
{{data.oldProperty = 12345 }} //【错误】ERROR in Template execution failed: TypeError: Cannot set property 'oldProperty' of undefined
{{$data.oldProperty = 12345 }} //【正确，并且会输出12345】

<% set data.oldProperty = 12345 %> //【错误】模板编译错误
<% set $data.oldProperty = 12345 %> //【错误】模板编译错误
<% data.oldProperty = 12345 %> //【错误】ERROR in Template execution failed: TypeError: Cannot set property 'oldProperty' of undefined
<% $data.oldProperty = 12345 %>//【正确，不会输出结果】
<%= $data.oldProperty = 12345 %>//【正确，并且会输出12345】
	
	2）上面正确的如下：
{{$data.newProperty = 12345 }} //【正确，并且会输出12345】
{{$data["newProperty"] = 12345 }} //【正确，并且会输出12345】

<% $data.newProperty = 12345 %>//【正确，不会输出结果】
<% $data["newProperty"] = 12345 %>//【正确，不会输出结果】
<%= $data.newProperty = 12345 %>//【正确，并且会输出12345】
<%= $data["newProperty"] = 12345 %>//【正确，并且会输出12345】

	3）支持同时设置多个相同的值
<% $data.newProperty1 = $data.newProperty2 = 12345 %>//【正确，不会输出结果】	

17、编译与显示
	1）简单示例
var render = template.compile(document.getElementById("tpl-test").innerHTML) //编译的结果是JavaScript函数
var html = render({fun1:(a,b)=>a+b, fun2:()=>new Date(),fun3:()=>new Date().toString(),fun4:function(){return "hello"}});
document.getElementById("result").innerHTML = html
	2）template.compile编译的结果是JavaScript函数。
	3）模板的集成方式
方式一：由客户端编译模板

方式二【未成功】：直接返回编译的结果函数的字符串，由客户端使用eval函数，类似new Function()的调用方式。
	1）可以保护模板的源代码
	2）效率比由客户端编译效率要高些（差别不是特别大）
	3）限制：
		1> 在Chrome扩展等限制unsafe-eval
Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' blob: filesystem:".
	4）【未成功】
		1> 函数源代码里有$import，使用下面代码会报错：无法找到$import的定义
let functionBody = render.toString().replace(/^function\(\$data\)\{/,"").replace(/\}$/, "")
console.log(functionBody)
let newRender = new Function("$data", functionBody)

方式三：由webpack编译模板：使用art-template-loader
【官方文档】https://aui.github.io/art-template/webpack/

18、代码块
	1）使用<% %>
	2）支持写多个语句
	3）支持JavaScript的注释语法