Skip to content

Mustache

TIP

Mustache 是一个零逻辑引擎的模板语言(Logic-less templates),mustache 是一个 js 模板,用于展示和 js 分离,它的优势在于可以应用在 Javascript、PHP、Python、Perl 等多种编程语言中。

一、简介

1、地址

2、名称

  • 英文:mustache.js - Logic-less templates with JavaScript
  • 中文:用 JS 编写的一个零逻辑引擎

3、特点

  • 只有标签,没有流程控制语句
  • 轻量级,比 freemark 和 valicity 要轻量级,20 多 K
  • 支持语言多
  • 除了 HTML 页面渲染,可以 用于配置文件、XML 渲染等各种文本文件

二、引入

1、常规引入

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <script src="https://cdn.bootcdn.net/ajax/libs/mustache.js/4.0.1/mustache.js"></script>

    <!-- 第一种 -->
    <script type="text/javascript">
      var data = {
        company: "Apple",
        address: {
          state: "CA ",
          zip: "95014 ",
        },
        product: ["Macbook ", "iPhone "],
        wrapped: function () {
          return function (text, render) {
            return "<b>" + render(text) + "</b>";
          };
        },
      };

      var tpl = `
			<h1>Hello {{company}}</h1>
			{{#address}} <p>{{street}},{{city}},{{state}}</p> {{/address}}
			{{#product}} <p>{{.}}</p> {{/product}}
			{{#wrapped}} {{company}} is awesome. {{/wrapped}}
		`;
      // 不带子模块的
      var html = Mustache.render(tpl, data);
      console.log(html);

      // 带子模块的
      var tpl = "<h1>{{company}}</h1> <ul>{{>address}}</ul>";
      var partials = {
        address: `{{#address}}
				<li>{{state}}</li>
				<li>{{zip}}</li>
			{{/address}}`,
      };
      var html = Mustache.render(tpl, data, partials);
      console.log(html);
    </script>

    <!-- 第二种 -->
    <script id="template" type="x-tmpl-mustache">
      {{name}}
    </script>
    <script type="text/javascript">
      var template = document.getElementById("template").firstChild.nodeValue;
      var r = Mustache.render(template, {
        name: "wan",
      });
      console.log(r);
    </script>
  </body>
</html>

2、编译引入

(1)、新建文件夹,生成 package.json 文件

bash
npm init -y

(2)、加载 mustache

bash
npm install mustache --save

(3)、修改 package.json 的执行脚本

bash
"scripts": {
	"build": "mustache dataView.json myTemplate.mustache > index.html"
}

(4)、新建 dataView.json 文件,放入数据

json
{
  "name": "<<<张三-zhangsan",
  "age": 20,
  "isTrue": true,
  "isFalse": false,
  "html": "<p style='color:red'>123</p>",
  "obj": {
    "name": "shenhao",
    "age": "19"
  },
  "isArray": [
    {
      "name": "a"
    },
    {
      "name": "b"
    },
    {
      "name": "c"
    }
  ],
  "empty": [],
  "strArr": ["Athos", "Aramis"]
}

(4)、新建模板 myTemplate.mustache,放入模板代码

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <div>字符串:{{name}} - {{{name}}} - {{&name}}</div>
    <div>数字:{{age}}</div>
    <div>
      boolean-true:
      <div>{{#isTrue}} 为true显示 {{/isTrue}}</div>
    </div>
    <div>
      boolean-false:
      <div>{{#isFalse}} 为false显示 {{/isFalse}}</div>
    </div>
    <div>html:{{&html}}</div>
    <div>对象:{{obj.name}} - {{obj.age}}</div>
    <div>
      数组遍历:
      <ul>
        {{#isArray}}
        <li>{{name}}</li>
        {{/isArray}}
      </ul>
    </div>
    <div>
      空数组:
      <div>
        {{#empty}}
        <p>test empty</p>
        {{/empty}}
      </div>
    </div>
    <div>
      if else 逻辑:
      <div>
        {{#empty}}
        <p>不为空显示</p>
        {{/empty}} {{^empty}}
        <p>为空显示</p>
        {{/empty}}
      </div>
    </div>
    <div>
      字符串数组:
      <div>
        {{#strArr}}
        <p>* {{.}}</p>
        {{/strArr}}
      </div>
    </div>
  </body>
</html>

(5)、运行命令进行编译,生成 index.html 文件

bash
npm run build

(6)、浏览器直接运行 index.html

(7)、最终的项目截图

mustache

三、模板

1、一个 htm 文件

html
<h1>Hello {{name}}, it is {{timeNow}}.</h1>

2、一个值是 html 代码的 js 变量

html
var template = "
<p>Hello {{name}}, it is {{timeNow}}.</p>
";

3、一个 script 片段

html
<script id="tpl-greeting" type="text/html">
  <dl>
    <dt>Name</dt>
    <dd>{{name}}</dd>
    <dt>Time</dt>
    <dd>{{timeNow}}</dd>
  </dl>
</script>

四、语法

1、变量

(1) 变量标记将当前上下文的变量通过模板渲染,如果当前上下文不存在该变量,则渲染为空串

js
{
  {
    变量名;
  }
}

(2) 默认变量会被经过 HTML 编码处理,如需显示原始值,用三个大括号或者在模板标记的初始加入 & 符号

js
{{{变量名 }}}
{{&变量名 }}

(3) 如果当前键为基本或对象,则渲染一次,如果为数组,则渲染数组长度次数。节点以 # 号开始,以 / 结束

json
// json数据
{
    "stooges": [
		{ "name": "张三" },
		{ "name": "李四" },
		{ "name": "王五" }
	]
}

// 模板
{{#stooges}}<b>{{name}}</b><br>{{/stooges}}

(4) 函数作为模板的变量,该函数会在当前列表的每一个元素的上下文迭代执行

js
var tpl = "{{#beatles}}* {{name}}<br/>{{/beatles}}";
var data = {
  beatles: [
    { firstName: "John", lastName: "Lennon" },
    { firstName: "Paul", lastName: "McCartney" },
  ],
  name: function () {
    return this.firstName + " " + this.lastName;
  },
};

(5) 如果节点键的值为函数,注意该函数在执行时的两个参数,第一个为该节点变量的直接值,第二个为函数,其执行的上下文对应视图对象

js
var template = "{{#bold}}Hi {{name}} {{lastName}}.{{/bold}}";
var view = {
  name: "John",
  lastName: "Lennon",
  bold: function () {
    return function (text, render) {
      return "<b>" + render(text) + "</b>";
    };
  },
};

2、render 渲染

  • 模板变量在上下找模板变量需要的数据进行填充
  • json 数据的 key 跟模板的变量对应就会填充,对应不上就不填充。生成展示代码没填充的变量不显示
  • 渲染函数:Mustache.render(template, data)
    1. data 为 json 数据,作为模板上下文
    2. template 为模板对象
    3. 返回渲染完成的 html 代码
js
//模板
var template = "<p>{{company}}</p>";
//数据
var data = {
  company: "Apple",
};

// 渲染
var html = Mustache.render(template, data);

五、用法

bash
// 7种写法

{{keyName}}
{{#keyName}} {{/keyName}}
{{^keyName}} {{/keyName}}
{{.}}
{{<partials}}
{{{keyName}}}  |  {{&keyName}}
{{!comments}}

第一种

js
// 1、{{keyName}}
// {{}}就是 Mustache 的标示符,花括号里的 keyName 表示键名,这句的作用是直接输出与键名匹配的键值

// 输入:
var data = {
  company: "Apple",
};
var tpl = "{{company}}";
var html = Mustache.render(tpl, data);

//输出:
Apple;

第二种

js
// 2、{{#keyName}} {{/keyName}}
// 以#开始、以/结束表示区块,它会根据当前上下文中的键值来对区块进行一次或多次渲染
// 注意:如果keyName值为 null, undefined, false;则不渲染输出任何内容

// 输入:
var data = {
  address: {
    state: "CA",
    zip: "95014 ",
  },
};
var tpl = `{{#address}} <p>{{state}},{{zip}}</p> {{/address}}`;
var html = Mustache.render(tpl, data);

//输出:
<p>CA,95014</p>;

第三种

js
// 3、{{^keyName}} {{/keyName}}
// 该语法与2类似,不同在于它是当 keyName 值为 null, undefined, false 时才渲染输出该区块内容

// 输入:
var data = {};
var tpl = `{{^nothing}}没找到 nothing 键名就会渲染这段{{/nothing}}`;
var html = Mustache.render(tpl, data);

//输出:
没找到 nothing 键名就会渲染这段

第四种

js
// 4、{{.}}
// {{.}}表示枚举,可以循环输出整个数组

// 输入:
var data = {
  product: ["Macbook ", "iPhone"],
};
var tpl = `{{#product}} <p>{{.}}</p> {{/product}}`;
var html = Mustache.render(tpl, data);

//输出:
<p>Macbook iPhone </p>;

第五种

js
// 5、{{>partials}}
// 以 > 开始表示子模块,如{{> address}};当结构比较复杂时,我们可以使用该语法将复杂的结构拆分成几个小的子模块

// 输入:
 var data = {
	"company": "Apple",
	"address": {
		"state": "CA",
		"zip": "95014 "
	}
};
var tpl = "<h1>{{company}}</h1> <ul>{{>address}}</ul>"
var partials = {
	address: "{{#address}} <p>{{state}},{{zip}}</p> {{/address}}"
}
var html = Mustache.render(tpl, data, partials);

//输出:
<h1>Apple</h1> <ul> <p>CA,95014 </p> </ul>

第六种

js
// 6、{{{keyName}}}  |  {{&keyName}}
// {{keyName}}输出会将等特殊字符转译,如果想保持内容原样输出可以使用{{{}}}或{{&}}

// 输入:
 var data = {
	"company": "<<<张三-zhangsan<br>"
};
var tpl = "<h1>{{{name}}}  -  {{&name}}</ul>"
var html = Mustache.render(tpl, data);

//输出:
<h1><<<张三-zhangsan<br>  -  <<<张三-zhangsan<br> </ul>

第七种

js
// 7、{{!comments}}
// !表示注释,注释后不会渲染输出任何内容

// 输入:
var data = {};
var tpl = "{{!这里是注释}}";
var html = Mustache.render(tpl, data);

//输出:

六、仓库

示例代码库

Released under the MIT License.