Vue源码解析之mustache模板引擎

一 介绍

模板引擎是将数据要变为视图最优雅的解决方案

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

纯DOM法、数据join法、ES6的反引导法、模板引擎

纯DOM法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="list"></ul>
    <script>
    var arr=[
        {"name":"小明","age":12,"sex":"男"},
        {"name": "小红","age":11,"sex":"女"},
         {"name":"小强","age":13,"sex":"男"}
]
var list=document.getElementById('list');
for(var i=0;i<arr.length;i++){
    let oli=document.createElement('li');
    oli.innerText=arr[i].name;
    //创建的节点是孤儿节点,所以必须要上树才能被用户看见
    //创建hd这个div
    let hdDiv = document . createElement('div');
     hdDiv.className = 'hd' ;
     hdDiv.innerText = arr[i].name+'的基本信息'; 
    //创建bd这个div
    let bdDiv = document . createElement( 'div' );
    bdDiv.className = 'bd' ;
    //创建三个p
    let p1 = document.createElement('p');
     p1.innerText = ' 姓名: ' + arr[i ] . name;
     bdDiv.appendChild(p1);
     let p2 = document . createElement('p');
      p2.innerText = '年龄'+arr[i].age ;
     bdDiv.appendChild(p2);
     let p3 = document . createElement('p');
     p3. innerText ='性别'+arr[i].sex;
     bdDiv.appendChild(p3);
     oli.appendChild(hdDiv);
     oli.appendChild(bdDiv);
     list.appendChild(oli);
}
    </script>
</body>
</html>

数组join法:( join 的参数 不可以省略,否则得到的 str 字符串会是以逗号间隔的)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
</head>
<body>
    <ul id="list"></ul>
    <script>
    var arr=[
        {"name":"小明","age":12,"sex":"男"},
        {"name": "小红","age":11,"sex":"女"},
         {"name":"小强","age":13,"sex":"男"}
]
var list=document.getElementById('list');
//遍历arr数组,每遍历-项,就以字符串的视角将HTML字符串添加到list中
for(let i=0;i<arr.length;i++){
list.innerHTML+=
[
'<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> '
].join('') 
}

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

ES6的反引导法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="list"></ul>
    <script>
    var arr=[
        {"name":"小明","age":12,"sex":"男"},
        {"name": "小红","age":11,"sex":"女"},
         {"name":"小强","age":13,"sex":"男"}
]
var list=document.getElementById('list');
//遍历arr数组,每遍历- -项,就以字符串的视角将HTML字符串添加到list中
for(let i=0;i<arr.length;i++){
    list.innerHTML +=`
     <li>
       <div class="hd">${arr[i].name}的基本信息</div>
        <div class="bd">
         <p>姓名: ${arr[i].name}</p>
         <p>性别: ${arr[i].sex}</p>
         <p>年龄: ${arr[i].age}</p>
        </div>
    </li>
`;
}
</script>
</body>
</html>

二 mustache基本语法

(1)渲染循环对象数组


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

    <!-- 模板 -->
    <!-- 在 es6 之前,没有 `` 的时候可以把 dom 模板写在 <script> 标签里,只要type 不写 text/javascript,浏览器就不会报错,也不会渲染。type 可以随便写,一般写成 text/template。
-->
    <script type="text/template" id="mytemplate">
        <ul>
            {{#arr}}
                <li>
                    <div class="hd">{{name}}的基本信息</div>    
                    <div class="bd">
                        <p>姓名:{{name}}</p>    
                        <p>性别:{{sex}}</p>    
                        <p>年龄:{{age}}</p>    
                    </div>
                </li>
            {{/arr}}
        </ul>
    </script>

    <script src="jslib/mustache.js"></script>
    <script>
        var templateStr = document.getElementById('mytemplate').innerHTML;

        var data = {
            arr: [
                { "name": "几斗", "age": 12, "sex": "男" },
                { "name": "亚瑟", "age": 11, "sex": "女" },
                { "name": "尉氏", "age": 13, "sex": "男" }
            ]
        };

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

(2)不循环

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

    <script src="jslib/mustache.js"></script>
    <script>
        var templateStr = `
            <h1>我买了一个{{thing}},好{{mood}}啊</h1>
        `;

        var data = {
            thing: '苹果',
            mood: '开心'
        };

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

(3)渲染循环简单数组

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

    <script src="jslib/mustache.js"></script>
    <script>
        var templateStr = `
            <ul>
                {{#arr}}
                    <li>{{.}}</li>    
                {{/arr}}
            </ul>
        `;

        var data = {
            arr: ['A', 'B', 'C']
        };

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

(4)数组的嵌套情况

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

    <script src="jslib/mustache.js"></script>
    <script>
        var templateStr = `
            <ul>
                {{#arr}}
                    <li>
                        {{name}}的爱好是:
                        <ol>
                            {{#hobbies}} 
                                <li>{{.}}</li>
                            {{/hobbies}} 
                        </ol>
                    </li>    
                {{/arr}}
            </ul>
        `;

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

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

(5)布尔值

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

    <script src="jslib/mustache.js"></script>
    <script>
        var templateStr = `
            {{#m}}
                <h1>你好</h1>
            {{/m}}
        `;

        var data = {
            m: false//看不见
            //m:true:看得见
        };

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

三 mustache库的机理

mustache库底层重点要做两个事情:
①将模板字符串编译为tokens形式
②将tokens结合数据,解析为dom字符串
 

tokens是一个JS的嵌套数组, 就是模板字符串的JS表示
它是“抽象语法树”、“虚拟节点”等等的鼾山鼻祖
 当模板字符串中有循环存在时,它将被编译为嵌套更深的tokens

 当循环是双重的,那么tokens会更深一层

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值