接触低代码后才认识了这个家伙:
- 提供丰富的语言特性和块继承、自动转移、宏和异步控制等等。
- 模板引擎就是基于模板配合数据构造出链输出的一个组件。
- 尽可能情况下,我们都需要读取数据后渲染模板,然后呈现给用户。故我们需要约会对应的模板引擎。
- 简单来说,Nunjucks就实现了在后台服务器显示内容的模板。
下面来看看一些使用方法
一、node上的基本使用
nunjucks.render(name, [context], [callback])
|
1 2 3 4 5 |
// 引用 import nunjucks from 'nunjucks'; // 渲染模板 var res = nunjucks.render('foo.html', { username: 'James' }); |
然后在模板foo.html中就可以使用username字段了
|
1 2 3 4 |
<body> {{username}} </body> |
二、多模板管理
在 node 端使用 FileSystemLoader 加载模板,浏览器端则使用 WebLoader 通过 http 加载(或使用编译后的模板)。
很显然,上面单独一个模板应用并不能满足日常需求,而对于低代码平台来说,模板的作用在于通过node生成对应的js文件,比如,我们要通过一个json来生成目标文件中的js方法等。
|
1 2 3 4 5 6 7 8 9 10 |
// 1、这句可以理解为模板引擎所识别的模板文件目录 const file_loader = new nunjucks.FileSystemLoader(moduleType, {}) // 2、模板引用实例化,这时候才算是引入路径 const env = new nunjucks.Environment(file_loader) // 3、渲染模板,获取渲染结果 let context = env.render('模板.js', {key: value}) // 4、生成新文件 creatFile(path, '目标文件.js', context) |
1、有几点需要注意的是,FileSystemLoader里的第二个参数可以为空,一般不常用,不过可以添加autoescape: true,nunjuck 会转义所有的输出,为了安全建议一直开启。
2、我们前面说了这是node生成代码,所以第3步中获取数据流context,在第4步中写入,path是目标文件路径。 3、在第2步后面,还可以添加一个addFilter,可以理解你给模板引擎定义了一个内置方法,在模板中使用数据变量的时候可以调用{{shorten|shorten}}。
|
1 2 3 4 |
env.addFilter('shorten', function(str, count) { return str.slice(0, count || 5); }); |
还有更多定义和参数方法,这里不再一一赘述,可以看官网,就目前这些方法应该可以满足一个复杂应用的使用。
三、模板使用
前面说了很多关于引用库文件的方法,下面就是重头戏了,也是大家最关心的模板问题,毕竟要通过模板生产目标文件的。
1、基本变量使用,前面我们是这么执行的env.render('模板.js', {key: value}),那么js里就可以直接使用
|
1 2 3 4 5 6 7 |
// 普通的js文件(当作模板) {{key}} // 如果key是一个对象,开发过程中还可以通过过滤实现完全输出 {{key|dump}} // 还记得前面我们通过addFilter定义了一个过滤器shorten,只不过dump是库给定义的,shorten是我们自定义的 {{key|shorten}} |
2、除了基本数据类型就是array、object了
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 这是一个html的引用 {% for item in usersArr%} <li> 姓名是: {{item.name}} 年龄是: {{item.age}} </li> {% endfor %} <!-- 注意在循环结束时,给一个结束的标志--> // 如果是js模板也一样,这里是循环eventDefinition,生成方法定义的过程 {% for key, value in eventDefinition %} {{ key }}={(e) => { (Events.{{ item.name }} && typeof {{ item.name }}_{{key}}_execute==='function') ? {{ item.name }}_{{key}}_方法名(e) : '' }} {% endfor %} |
3、条件判断,就像写js一样,有着各种语法
|
1 2 3 4 5 6 |
{% if arr.length===0 %} {{ "直接输出:没数据" }} {% else %} {{"这是第一个结果:"+arr[0]}} {% endif %} |
4、再看一个复杂一点的。这里通过macro定义了一个方法traverseArry,这样你在模板中就可以使用这个方法了。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
{% macro traverseArry(array) %} {% for item in array %} {% if item is object%} { {% for k , v in item %} {{k}} : {{v|safe}}, {% endfor %} }, {% else %} {{ item|safe}} {% endif %} {% endfor %} {% endmacro %} |
综上来看,Nunjucks在逻辑上跟我们常见的js没有太大区别,主要的还是语法问题,是不是挺简单的。
四、注意事项
1、模块加载
我们在模板中可以加载另一个模板js,这样才有了上面macro定义方法达到共用的目的,除了这种定向的,我们在实际应用中也会遇到动态加载的问题,你可能想到用条件判断进行import,比如:
|
1 2 3 4 5 6 |
{% if usePubTemp %} {% import "../模板1.js" as Common %} {% else %} {% import "新路径/模板2.js" as Common %} {% endif %} |
但是你这样会发现,它加载失败了,因为import外不可条件判断,正确的做法是定义一个路径变量
|
1 2 3 4 5 6 7 8 |
{% if usePubTemp %} {% set templatePath = "../模板1.js" %} {% else %} {% set templatePath = "新路径/模板2.js" %} {% endif %} {% import templatePath as Common %} |
2、多模板载入
上面我们进行了路径条件判断实现不同模板加载的方式,但是有个容易忽略的问题,就是新路径新路径/模板2.js也要在node中添加到,否则识别不到。前面我们说Environment来实例化模板路径,它第一个参数可以传一个路径,也可以是路径数组,可以支持多个路径的情况。
3、js语法和模板语法混用
很明显两者语法思路一样,写法不同,在写js模板的时候要特别注意,到底是要做逻辑还是要输出,否则很容易出现错误的结果。
|
1 2 3 4 5 6 7 |
// 比如模块加载,你体会一下会变成什么 {% if usePubTemp %} {{ import "../模板1.js" as Common }} {% else %} {{ import "新路径/模板2.js" as Common }} {% endif %} |
好了,以上就是js模板引擎Nunjucks的一些常见使用方法了,有兴趣的同学可以试试。