模板渲染学习

应用场景

前端如angular 和 vue 都有模板指令,后端express也可以配合使用多种模块引擎,这些大部分都是模板渲染

要点

将模块按照规则合成一个Function实例,然后调用

例子,实现模板引擎ejs的for功能

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板渲染</title>
    <style>
    </style>
</head>
<body>
<div id="list">
</div>
<!--
    模板放置的地方,由于设置了type,所以浏览器不会把这当作JavaScript来运行
-->
<script type="text/template" id="templs">
<ul>
    <% for(var i in obj){ %>
        <li><%= obj[i].text %>:<%= obj[i].status %></li>
    <% } %>
</ul>

</script>
<script src="mytempltes.js"></script>
<script>
new Template({
    el:"list",// 渲染节点
    tem:"templs", // 模板节点
    data:[
        {
            text:"大前端",status:"火热"
        },
        {
            text:"大前端2",status:"火热2"
        }
    ]
});

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

mytempltes.js

(function(win,factory){

    win.Template = factory;

})(this,function(options){//options就是传入的对象
    //匹配指定的字符:A:<% ... %>  B:<%= %>
    var matcher = /<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$/g;//这个正则不是去匹配,而是根据正则替换
    var el = document.getElementById(options.el);
    var tem = document.getElementById(options.tem).innerHTML;
    var data = options.data;

    var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;//特殊字符列表
    //空格:$nbsp;  &glt;....
    var escapers = {//匹配需要匹配的字段,替换为指定的字段
        "'":"'",
        "\\":"\\",
        "\r":"r",
        "\n":"n",
        "\t":"t",
        "\u2028":"u2028",
        "\u2029":"u2029"
    }

    //XSS攻击:传入一些特殊的字符,以混淆JS,传入进来,导致程序错误或者出现Bug
    var template = function(text,data){//处理业务逻辑
        /*
            由于语法特殊,如果单纯的通过if或者其他判断,肯定不能达到理想的效果
            就需要根据已有的模板字符来动态创建方法

         */
        var index = 0;
        var function_body = "var dataHtml = '';";
        function_body += "dataHtml += '";
        text.replace(matcher,function(match,interlpolate,evaluate,offset){
            /*
                match:被匹配的模板字符
                interlpolate:已经替换的字符
                evaluate:已经替换的字符
                offset:被替换字符的下标位置

                指定字符串的位置:text.slice(起始位置,结束位置)
             */
            function_body += text.slice(index,offset)
                .replace(escaper,function(match){
                    return '\\' + escapers[match];//因为没有指定的字符
            });

            if(evaluate){
                function_body += "';"+evaluate+"dataHtml += '";
            }
            if(interlpolate){
                function_body += "' + " + interlpolate + " + '";
            }
            index = offset + match.length;//已有的长度+字符的长度 = 下一个的长度
            return match;
        });

        function_body += "';return dataHtml";
        //此时render已经是一个动态的方法了
        var render = new Function('obj',function_body);//通过new Functionn得到一个通过字符串生成的动态方法
        return render(data);

    }
    el.innerHTML = template(tem,data);



});

如果觉得文章对你有点用的话,麻烦拿出手机,这里有一个你我都有的小福利(每天一次): 打开支付宝首页搜索“8601304”,即可领红包。谢谢支持

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容