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模板引擎的主要内容,如果未能解决你的问题,请参考以下文章

vue底层之mustache初识

Js模板引擎mustache

Vue源码-手写mustache源码

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

nodejs+Express中使用mustache模板引擎

深度学习mustache