# 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、常规引入

<!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文件

npm init -y

(2)、加载mustache

npm install mustache --save

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

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

(4)、新建dataView.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,放入模板代码

<!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文件

npm run build

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

(7)、最终的项目截图

mustache

# 三、模板

# 1、一个htm文件

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

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

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

# 3、一个script片段

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

# 四、语法

# 1、变量

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

{{变量名 }}

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

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

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

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

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

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

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) 如果节点键的值为函数,注意该函数在执行时的两个参数,第一个为该节点变量的直接值,第二个为函数,其执行的上下文对应视图对象

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代码
//模板
var template = "<p>{{company}}</p>";
//数据
var data = {
	"company": "Apple",
};

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

# 五、用法

// 7种写法

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

# 第一种

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

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

//输出:
Apple

# 第二种

// 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>

# 第三种

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

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

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

# 第四种

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

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

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

# 第五种

// 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>

# 第六种

// 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>

# 第七种

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

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

//输出:

# 六、仓库

示例代码库