mustache模板引擎

Posted webchang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mustache模板引擎相关的知识,希望对你有一定的参考价值。


一、前言

模板引擎是将数据变为视图最优雅的解决方案
在这里插入图片描述

历史上曾经出现的数据变为视图的方法

  • 纯DOM法:直接操作DOM,非常笨拙
  • 数组join法:利用数组的join('')方法将html代码拼接为字符串,并使用xxx.innerHTML添加到DOM上
  • ES6的反引号法:ES6中新增的${a}语法糖,很好用
  • 模板引擎:解决数据变为视图的最优雅的方法

我们以上边图片中展示的例子,对每种方法分别进行使用:

1、纯DOM法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>1</title>
</head>
<body>

<ul id="list"></ul>

<script>
  let arr = [
    {name: '小明', age: 12, sex: '男'},
    {name: '小红', age: 11, sex: '女'},
    {name: '小王', age: 13, sex: '男'}
  ];

  let list = document.getElementById('list');

  for (let i = 0; i < arr.length; i++) {
    let li = document.createElement('li');

    let hdDiv = document.createElement('div');
    hdDiv.classList.add('hd');
    hdDiv.innerText = arr[i].name + '的基本信息';

    let bdDiv = document.createElement('div');
    bdDiv.classList.add('bd');
    for(let key in arr[i]) {
      let str = '';
      let value = arr[i][key];
      if (key === 'name') {
        str = '姓名:' + value;
      } else if (key === 'age') {
        str = '年龄:' + value;
      } else {
        str += '性别:' + value;
      }
      let p = document.createElement('p');
      p.innerText = str;
      bdDiv.appendChild(p);
    }
    li.appendChild(hdDiv);
    li.appendChild(bdDiv);

    list.appendChild(li);
  }
</script>
</body>
</html>

在这里插入图片描述

2、使用数组的join方法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>2</title>
</head>
<body>

<ul id="list"></ul>

<script>
  let arr = [
    {name: '小明', age: 12, sex: '男'},
    {name: '小红', age: 11, sex: '女'},
    {name: '小王', age: 13, sex: '男'}
  ];

  let list = document.getElementById('list');

  let htmlStr = '';
  for (let i = 0; i < arr.length; i++) {
    let str = [
      '<li>',
        '<div className="hd">' + arr[i].name + '的基本信息</div>',
        '<div className="bd">',
          '<p>姓名:' + arr[i].name +  '</p>',
          '<p>年龄:' + arr[i].age +  '</p>',
          '<p>性别:' + arr[i].sex +  '</p>',
        '</div>',
      '</li>'
    ].join('');
    htmlStr += str;
  }
  list.innerHTML = htmlStr;

</script>
</body>
</html>

3、使用ES6的反引号

ES6中的反引号拼接字符串的时候可以换行。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>3</title>
</head>
<body>

<ul id="list"></ul>

<script>
  let arr = [
    {name: '小明', age: 12, sex: '男'},
    {name: '小红', age: 11, sex: '女'},
    {name: '小王', age: 13, sex: '男'}
  ];

  let list = document.getElementById('list');

  let htmlStr = '';
  for (let i = 0; i < arr.length; i++) {
    let str = `
      <li>
        <div class="hd">${arr[i].name}的基本信息</div>
        <div class="bd">
          <p>姓名:${arr[i].name}</p>
          <p>年龄:${arr[i].age}</p>
          <p>性别:${arr[i].sex}</p>
        </div>
      </li>`;
    htmlStr += str;
  }
  list.innerHTML = htmlStr;

</script>
</body>
</html>

二、mustache简介

mustache官方git: https://github.com/janl/mustache.js

mustache是“胡子”的意思,因为它的嵌入标记{{ }}非常像胡子,{{ }}的语法也被vue沿用。mustache.js 是一个简单强大的 JavaScript 模板引擎,使用它可以简化在 js 代码中的 html 编写。它比Vue诞生的早多了,它的底层实现机理在当时是非常有创造性的、轰动性的,为后续模板引擎的发展提供了崭新的思路。

必须要引入mustache库,可以在bootcdn.com上找到它:https://cdn.bootcdn.net/ajax/libs/mustache.js/4.0.1/mustache.js

基本使用:Mustache.render(templateStr, data),第一个参数是模板字符串,第二个参数是对象,返回值是拼接好的html字符串。

1、基本使用

<div id="container"></div>

<script src="https://cdn.bootcdn.net/ajax/libs/mustache.js/4.0.1/mustache.js"></script>
<script>
  let templateStr = `<h1>我买了{{thing}},很{{mood}}</h1>`
  let data = {
    thing:'手机',
    mood:'很开心'
  };
  
  let domStr = Mustache.render(templateStr,data);
  let container = document.getElementById('container');
  container.innerHTML = domStr;
</script>

在这里插入图片描述

2、循环

普通数组

如果是普通的数组,如['A', 'B', 'C'],使用 . 代表数组的每一项。

let templateStr = `
  <ul>
    {{#arr}}
      <li>{{.}}</li> 
    {{/arr}}
  </ul>`;
  
let data = {
  arr: ['A', 'B', 'C']
};

let domStr = Mustache.render(templateStr, data);
let container = document.getElementById('container');
container.innerHTML = domStr;

对象数组

如果是对象数组,可以直接使用对象中的属性,使用mustache实现上边的案例,

<div id="container"></div>

<script src="https://cdn.bootcdn.net/ajax/libs/mustache.js/4.0.1/mustache.js"></script>
<script>
  let container = document.getElementById('container');
  console.log(Mustache); // 引入mustache.js后就可以使用 Mustache 对象
  
  let templateStr = `
    <ul>
      {{#arr}}
        <li>
          <div class="hd">{{name}}的基本信息</div>
          <div class="bd">
            <p>姓名:{{name}}</p>
            <p>年龄:{{age}}</p>
            <p>性别:{{sex}}</p>
          </div>
        </li>;
      {{/arr}}
    </ul>`;
    
  // 数据对象
  let data = {
	   arr: [
	     {name: '小明', age: 12, sex: '男'},
	     {name: '小红', age: 11, sex: '女'},
	     {name: '小王', age: 13, sex: '男'}
	   ]
  };
  let domStr = Mustache.render(templateStr, data);

  container.innerHTML = domStr;
</script>

嵌套数组

let templateStr = `
  <ul>
    {{#arr}}
      <li>{{name}}的爱好是:
        <ol>
        {{#hobbies}}
          <li>{{.}}</li>
        {{/hobbies}}
        </ol>
      </li>
    {{/arr}}
  </ul>`;

let data = {
  arr: [
    {name: '小明', age: 12, hobbies: ['游泳','羽毛球']},
    {name: '小红', age: 11, hobbies: ['编程','写作文']},
    {name: '小王', age: 13, hobbies: ['看报纸']}
  ]
};

let domStr = Mustache.render(templateStr, data);
let container = document.getElementById('container');
container.innerHTML = domStr;

在这里插入图片描述

3、使用布尔值

let templateStr = `
  {{#m}}
    <h1>你好</h1>
  {{/m}}
`;

let data = {
  m:false // 当 m 是false时,不会显示
};

let domStr = Mustache.render(templateStr, data);
let container = document.getElementById('container');
container.innerHTML = domStr;

4、使用模板

换个地方写模板代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>9</title>
</head>
<body>

<div id="container"></div>

<!--这个script标签中的内容不会显示到页面上,即使有js代码也不会执行-->
<!--所以我们就可以在这个地方写html模板的代码-->
<script type="text/template" id="template">
  <ul>
    {{#arr}}
    <li>
      <div class="hd">{{name}}的基本信息</div>
      <div class="bd">
        <p>姓名:{{name}}</p>
        <p>年龄:{{age}}</p>
        <p>性别:{{sex}}</p>
      </div>
    </li>
    {{/arr}}
  </ul>
</script>
<script src="https://cdn.bootcdn.net/ajax/libs/mustache.js/4.0.1/mustache.js"></script>
<script>
  let data = {
    arr: [
      {name: '小明', age: 12, sex: '男'},
      {name: '小红', age: 11, sex: '女'},
      {name: '小王', age: 13, sex: '男'}
    ]
  };

  let container = document.getElementById('container');
  
  let templateStr = document.getElementById('template').innerHTML;
  let domStr = Mustache.render(templateStr, data);
  container.innerHTML = domStr;
</script>
</body>
</html>

三、mustache的底层机理

mustache库不能用简单的正则表达式思路实现。

在较为简单的示例情况下,可以用正则表达式结合replace方法实现

字符串的replace方法

<div id="container"></div>

<script src="https://cdn.bootcdn.net/ajax/libs/mustache.js/4.0.1/mustache.js"></script>
<script>
  let templateStr = `<h1>我买了{{thing}},心情{{mood}}</h1>`;
  let data = {
    thing: '手机',
    mood: '很开心'
  };

  // 最简单的模板引擎的实现机理,利用的是replace()方法。
  // replace()的第二个参数可以是一个函数,这个函数提供捕获的东西的参数,就是$1
  // 结合data对象,即可进行智能的替换
  function render(templateStr, data) {
    return templateStr.replace(/\\{\\{(\\w+)\\}\\}/g, function (match, $1) {
      return data[$1];
    })
  }

  let htmlStr = render(templateStr,data);
  let container = document.getElementById('container');
  container.innerHTML = htmlStr;
</script>

1、mustache底层机理

在这里插入图片描述
mustache库底层重点要做两个事情:

  • 将模板字符串编译为tokens形式
  • 将tokens结合数据,解析为dom字符串

2、tokens

tokens是一个JS的嵌套数组,就是模板字符串的JS表示。它是“抽象语法树”、“虚拟节点”等等的开山鼻祖。
在这里插入图片描述

在这里插入图片描述
循环情况下的tokens:
在这里插入图片描述


未完待续……

学习资料:https://www.bilibili.com/video/BV1EV411h79m

前端学习交流QQ群:862748629 点击加入

以上是关于mustache模板引擎的主要内容,如果未能解决你的问题,请参考以下文章

mustache模板引擎

mustache模板引擎

JavaScript中template模板引擎

Vue源码-手写mustache源码

使用mustache.js 模板引擎输出html

nodejs+Express中使用mustache模板引擎