Javascript:自己寫模板引擎


背景

因為JS沒有提供“字符串插入”和“多行字符串”特性,傳統的拼湊字符串容易出錯、性能不高和不容易理解代碼,為了應對這些問題,很多個人和團隊開發了模板引擎,現在主流的JS框架幾乎都提供此類功能了。

模板引擎的實現方式有很多種,此處介紹一種簡單、靈活和強大的思路,該方式借鑒了 JSP(web 服務器最終將 JSP 頁面轉換為了 Servlet),編譯后會把模板轉換為一個方法。

這個實現只是為團隊介紹模板引擎的原理,具體應用還需要選擇成熟的開源實現。

實現

 1 <!DOCTYPE html>
 2 
 3 <html xmlns="http://www.w3.org/1999/xhtml">
 4 <head runat="server">
 5     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 6     <title></title>
 7 </head>
 8 <body>
 9 </body>
10 </html>
11 <script id="test-tpl" type="text/template">
12 start
13 
14 <# for(var i=0; i< items.length; i++) {#>
15     <#= items[i].name #>
16 <# } #>
17 
18 end
19 </script>
20 <script type="text/javascript">
21     var Template = function (tpl) {
22         var me = this;
23 
24         me.tpl = tpl;
25     };
26 
27     Template.prototype.compile = function () {
28         var me = this;
29 
30         var codes = [];
31         codes.push("var results = [];");
32         codes.push("with(context) {");
33 
34         var frags = me.tpl.split(/(<#=.+?#>)|(<#.+?#>)/);
35         for (var i = 0; i < frags.length  ; i++) {
36             var frag = frags[i];
37 
38             if (!frag) {
39                 continue;
40             }
41             if (frag.indexOf("<#=") == 0) {
42                 codes.push("results.push(" + frag.substring(3, frag.length - 2) + ");");
43             }
44             else if (frag.indexOf("<#") == 0) {
45                 codes.push(frag.substring(2, frag.length - 2));
46             }
47             else {
48                 codes.push("results.push('" + frag.split('\n').join('\\n') + "');");
49             }
50         }
51 
52         codes.push("}");
53         codes.push("return results.join('');");
54 
55         console.log(codes.join("\n"));
56         me.compiledTplFun = new Function("context", codes.join("\n"));
57     };
58 
59     Template.prototype.apply = function (context) {
60         var me = this;
61 
62         if (!me.compiledTplFun) {
63             me.compile();
64         }
65 
66         return me.compiledTplFun(context);
67     };
68 
69     var tpl = new Template(document.getElementById("test-tpl").innerHTML)
70 
71     console.log(tpl.apply({ items: [{ name: "dgw" }] }));
72 </script>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM