Skip to content

模板引擎

‌ 模板引擎 ‌ 是一种用于将数据和模板结合生成最终文本输出的工具,广泛应用于软件开发中,特别是在需要生成大量重复格式的文本时,如 HTML 页面、邮件模板、代码文件等。其主要作用是快速生成动态页面、提高开发效率,减少重复代码的编写,同时降低维护成本,使代码更加清晰易懂

其工作原理通常包括以下几个步骤:

  • 数据填充 ‌:将业务数据填充到模板中的占位符或标记位置。
  • ‌ 模板渲染 ‌:根据数据生成最终的文本输出,如 HTML 页面、邮件内容等。
  • ‌ 输出显示 ‌:将生成的文本输出展示给用户。

常见的模板引擎及其特点

  • ‌JSP‌:功能强大,支持 Java 代码编写,性能较好,适合官方标准。
  • ‌Freemarker‌:性能良好,支持严格的 MVC 分离,使用方便,但用户群体较少。
  • ‌Thymeleaf‌:基于 HTML 的模板引擎,支持动静分离,易于与 Spring 框架集成,适合现代 Web 开发。
  • art-template: 是一个简约、超快的模板引擎

sodajs 模板引擎

目前感觉最好用的指令模板引擎。其特性有:

  • 超小体积(gzip 之后只有 4K)
  • 支持 dom 指令系统
  • 良好的兼容性,兼容 ie8 及现代浏览器,兼容 node 环境
  • 避免输出的 xss 漏洞
  • 高性能 dom 渲染引擎
  • 与 AngularJS 指令兼容,使用非常方便
  • 自定义指令和前缀

安装:npm install --save sodajs

使用

js
import soda from "sodajs";

// 自定义指令前缀,默认前缀时soda-。设置为v-,类似vue模板语法
soda.prefix("v-");

// 自定义过滤器,并接收参数,用法类似vue
soda.filter("nameFilter", function (input, length) {
  return (input || "").substr(0, length);
});

/** 自定义指令
 * scope: 当前的scope数据
 * el: 当前节点
 * expression: 指令的表达式原始字符串
 * parseSodaExpression: 解析soda表达式
 * getValue: 从data链式获取值
 * compileNode: 继续编译节点
 * document: 使用document参数而不是使用window.document, 这样可以在node环境下去用
 */
soda.directive("mydirective", {
  priority: 8,
  link({
    scope,
    el,
    parseSodaExpression,
    expression,
    getValue,
    compileNode,
    document,
  }) {
    // how to compile el
    getValue({ a: { b: 1 } }, "a.b"); // ===>   1
    parseSodaExpression("{{1 + 2 + a}}", { a: 1 }); // ===> 4
    var value = parseSodaExpression(expression);
    if (value) {
      var textNode = document.createTextNode(value);
      el.appendChild(textNode);
    }
  },
});

// 定义子模板
soda.discribe("tmpl1", `<h1>{{name}}</h1>`, {
  compile: false, // 是否编译子模板的变量
});
// 子模板可以定义为函数,接收参数
soda.discribe("tmpl2", function (path) {
  return `<h1>{{name}}_${path}</h1>`;
  // return fs.readFileSync(path, 'utf-8'); // node环境里,返回读取的文件
});

// 定义模板
const tpl = ` 
<div v-if="show">条件渲染, 使用变量:{{name}}</div>
<div v-if="!show">I\'m hidden!</div>

<div v-html="html">渲染原始HTML</div>
<div v-replace="html">用html替换当前结点</div>

<div v-include="tmpl1">使用定义的子模板,替换当前节点</div>
<div v-include="tmpl2:view.html">使用函数形式的子模板接收view.html参数,替换当前节点</div>

<div v-class="show ? 'active' : ''">自定义class</div>
<div v-style="style">自定义style</div>

<div v-checked="{{false}}">false 或者 "", 该属性就会被移除,否则,会被添加上去</div>
<div v-src="hello{{name}}.png">自定义src</div>

<div v-mydirective="add one tips: {{name}}">使用自定义指令</div>

<ul>
    <li v-repeat="(index,item) in list by name" v-if="item.show">
        循环渲染 $index:默认索引,也可以明确索引index dom的key为name
        {{item.name}}
        {{$index}}
        {{index}}
        {{item.name|nameFilter:10}}
    </li>
</ul>
`;

// 定义传入模板的数据
var data = {
  show: true,
  html: '<span style="color:red;">test soda-html</span>',
  style: { width: "100px", height: "100px" },
  list: [
    { name: "Hello", show: true },
    { name: "sodajs", show: true },
    { name: "AlloyTeam" },
  ],
};

document.body.innerHTML = soda(tpl, data);

自定义 node 端的 dom 解析引擎。soda.node 版本的默认 dom 解析引擎是 nodeWindow,你可以用这个方法替换为 jsdom 等

js
var document = require("document");
var soda = require("soda");

soda.setDocument(document);

根据 MIT 许可证发布