zhengwei1949 / myblog

个人博客
10 stars 6 forks source link

模板引擎原理理解 #105

Open zhengwei1949 opened 6 years ago

zhengwei1949 commented 6 years ago
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>

    </script>
</head>
<body>
    <div id="container"></div>
    <script type="text/template" id="tpl">
        <h1>{{name}}</h1>
        <ul>
            {{each list v i}}
                <li>{{v}}</li>
            {{/each}}
        </ul>
    </script>
    <script>
    //这个例子的目的是为了让对模板引擎原理有兴趣的同学简单的了解一下
    //这块是模仿template方法,要传入二个参数,第一个参数是模板的id,第二个参数是要渲染的数据
    //思路分析:先提取出来使用了{{each}}{{/each}}中间的内容,把循环的数组和这块的内容手动的进行循环渲染出最终的内容之后,然后再替换成最终的内容
    //接下来再把普通的变量的渲染的内容渲染出来,然后把最终的结果返回回去
    function template(tplId,data){
        var demo = document.getElementById(tplId);
        var str = demo.innerHTML;
        str = str.replace(/\n/g, '');//去掉所有的换行符,简化操作
        if(str.indexOf('{{') > -1){//如果确实有{{}}的话,则继续
            //先把循环解决掉
            if(str.indexOf('{{each') > -1){
                //说明是循环
                // console.log(str)
                var reg = /\{\{each.*?\}\}(.*)\{\{\/each\}\}/mg;//这里的?的意思是采用的是非贪婪模式 这块的目的是把循环中间的内容提取出来
                // console.log(reg.exec(str));
                var a = reg.exec(str);//匹配出来{{中间的内容}}
                var myStr = a[1];//获得中间的内容
                var myStr1 = a[0];//获得整个匹配的内容
                // console.log(a)
                // return;
                var reg1 = /{{each\s+(.*?)\s+v/;
                var arr1 = data[reg1.exec(str)[1]];
                // console.log(arr1);
                var tempHtml = '';
                for(var i=0;i<arr1.length;i++){
                    // <li>{{v}}</li>
                    tempHtml = tempHtml + myStr.replace('{{v}}',arr1[i]);
                }
                // console.log(tempHtml);    
            }
            str = str.replace(myStr1,tempHtml);
            // console.log(str);
            for(var i in data){
                str = str.replace('{{'+i+'}}',data[i]);
            }
            // console.log(str);
            return str;
            }
    }

    var data = {
            name: "水果列表",
            list: ['苹果', '香蕉', '桔子', '草莓']
        };

    var html = template('tpl',data);
    document.getElementById('container').innerHTML = html;

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