接触低代码后才认识了这个家伙:
- 提供丰富的语言特性和块继承、自动转移、宏和异步控制等等。
- 模板引擎就是基于模板配合数据构造出链输出的一个组件。
- 尽可能情况下,我们都需要读取数据后渲染模板,然后呈现给用户。故我们需要约会对应的模板引擎。
- 简单来说,Nunjucks就实现了在后台服务器显示内容的模板。
下面来看看一些使用方法
一、node上的基本使用
nunjucks.render(name, [context], [callback])
// 引用
import nunjucks from 'nunjucks';
// 渲染模板
var res = nunjucks.render('foo.html', { username: 'James' });
然后在模板foo.html中就可以使用username字段了
<body>
{{username}}
</body>
二、多模板管理
在 node 端使用 FileSystemLoader
加载模板,浏览器端则使用 WebLoader
通过 http 加载(或使用编译后的模板)。
很显然,上面单独一个模板应用并不能满足日常需求,而对于低代码平台来说,模板的作用在于通过node生成对应的js文件,比如,我们要通过一个json来生成目标文件中的js方法等。
// 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}}
。
env.addFilter('shorten', function(str, count) {
return str.slice(0, count || 5);
});
还有更多定义和参数方法,这里不再一一赘述,可以看官网,就目前这些方法应该可以满足一个复杂应用的使用。
三、模板使用
前面说了很多关于引用库文件的方法,下面就是重头戏了,也是大家最关心的模板问题,毕竟要通过模板生产目标文件的。
1、基本变量使用,前面我们是这么执行的env.render('模板.js', {key: value})
,那么js里就可以直接使用
// 普通的js文件(当作模板)
{{key}}
// 如果key是一个对象,开发过程中还可以通过过滤实现完全输出
{{key|dump}}
// 还记得前面我们通过addFilter定义了一个过滤器shorten,只不过dump是库给定义的,shorten是我们自定义的
{{key|shorten}}
2、除了基本数据类型就是array、object了
// 这是一个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一样,有着各种语法
{% if arr.length===0 %}
{{ "直接输出:没数据" }}
{% else %}
{{"这是第一个结果:"+arr[0]}}
{% endif %}
4、再看一个复杂一点的。这里通过macro
定义了一个方法traverseArry
,这样你在模板中就可以使用这个方法了。
{% 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,比如:
{% if usePubTemp %}
{% import "../模板1.js" as Common %}
{% else %}
{% import "新路径/模板2.js" as Common %}
{% endif %}
但是你这样会发现,它加载失败了,因为import
外不可条件判断,正确的做法是定义一个路径变量
{% if usePubTemp %}
{% set templatePath = "../模板1.js" %}
{% else %}
{% set templatePath = "新路径/模板2.js" %}
{% endif %}
{% import templatePath as Common %}
2、多模板载入
上面我们进行了路径条件判断实现不同模板加载的方式,但是有个容易忽略的问题,就是新路径新路径/模板2.js
也要在node中添加到,否则识别不到。前面我们说Environment
来实例化模板路径,它第一个参数可以传一个路径,也可以是路径数组,可以支持多个路径的情况。
3、js语法和模板语法混用
很明显两者语法思路一样,写法不同,在写js模板的时候要特别注意,到底是要做逻辑还是要输出,否则很容易出现错误的结果。
// 比如模块加载,你体会一下会变成什么
{% if usePubTemp %}
{{ import "../模板1.js" as Common }}
{% else %}
{{ import "新路径/模板2.js" as Common }}
{% endif %}
好了,以上就是js模板引擎Nunjucks的一些常见使用方法了,有兴趣的同学可以试试。