laytpl
是 Layui 的一款轻量 JavaScript 模板引擎,在字符解析上有着比较出色的表现。
在以下模板或数据中进行编辑,下方视图将呈现对应结果。
01.<!DOCTYPE html>02.<html>03.<head>04. <meta charset="utf-8">05. <meta name="viewport" content="width=device-width, initial-scale=1">06. <title>Demo</title>07. <!-- 请勿在项目正式环境中引用该 layui.css 地址 -->08. <link href="/laydev/staticdev/layui/v/2.9.18/css/layui.css" rel="stylesheet">09.</head>10.<body>11.<style>12..laytpl-demo{border: 1px solid #eee;}13..laytpl-demo:first-child{border-right: none;}14..laytpl-demo>textarea{position: relative; display: block; width:100%; height: 300px; padding: 11px; border: 0; box-sizing: border-box; resize: none; background-color: #fff; font-family: Courier New; font-size: 13px;}15..laytpl-demo>div:first-child{height: 32px; line-height: 32px; padding: 6px 11px; border-bottom: 1px solid #eee; background-color: #F8F9FA;}16.</style>17.<div class="layui-row">18. <div class="layui-col-xs6 laytpl-demo">19. <div>模板</div>20. <textarea id="ID-tpl-src">21.<h3>{{= d.title }}</h3>22.<ul>23.{{# layui.each(d.list, function(index, item){ }}24. <li>25. <span>{{= item.modname }}</span>26. <span>{{= item.alias }}:</span>27. <span>{{= item.site || '' }}</span>28. </li>29.{{# }); }}30.<p>{{# if(d.list.length === 0){ }}31.无数据32.{{# } }}</p>33.</ul>34. </textarea>35. </div>36. <div class="layui-col-xs6 laytpl-demo">37. <div>数据</div>38. <textarea id="ID-tpl-data">39.{40. "title": "Layui 常用模块",41. "list": [42. {43. "modname": "弹层",44. "alias": "layer",45. "site": "layer.domain.com"46. },47. {48. "modname": "表单",49. "alias": "form"50. },51. {52. "modname": "表格",53. "alias": "table"54. },55. {56. "modname": "日期",57. "alias": "laydate"58. },59. {60. "modname": "上传",61. "alias": "upload"62. }63. ]64.}65. </textarea>66. </div>67. <div class="layui-col-xs12 laytpl-demo" style="border-top: none;">68. <div class="layui-row">69. <div class="layui-col-xs6">视图</div>70. <div class="layui-col-xs6" style="text-align: right">71. <span id="ID-tpl-viewtime"></span>72. </div>73. </div>74. <div class="layui-padding-sm" id="ID-tpl-view" style="max-height: 300px; padding: 16px; overflow: auto;">…</div>75. </div>76.</div>77.<div class="layui-clear"></div>78. 79.<!-- 请勿在项目正式环境中引用该 layui.js 地址 -->80.<script src="/laydev/staticdev/layui/v/2.9.18/layui.js"></script> 81.<script>82.layui.use(function(){83. var laytpl = layui.laytpl;84. var util = layui.util;85. var $ = layui.$;86. // 获取模板和数据87. var get = function(type){88. return {89. template: $('#ID-tpl-src').val(), // 获取模板90. data: function(){ // 获取数据91. try {92. return JSON.parse($('#ID-tpl-data').val());93. } catch(e){94. $('#ID-tpl-view').html(e);95. }96. }()97. };98. };99. 100. var data = get();101. 102. // 耗时计算103. var startTime = new Date().getTime(), timer = function(startTime, title){104. var endTime = new Date().getTime();105. $('#ID-tpl-viewtime').html((title || '模板解析耗时:')+ (endTime - startTime) + 'ms');106. };107. // 渲染模板108. var thisTpl = laytpl(data.template);109. // 执行渲染110. thisTpl.render(data.data, function(view){111. timer(startTime);112. $('#ID-tpl-view').html(view);113. });114. 115. // 编辑116. $('.laytpl-demo textarea').on('input propertychange', function(){117. var data = get();118. if(!data.data) return;119. 120. // 计算模板渲染耗时121. var startTime = new Date().getTime();122. 123. // 若模板有变化,则重新解析模板;若模板没变,数据有变化,则从模板缓存中直接渲染(效率大增)124. if(this.id === 'ID-tpl-src'){ 125. thisTpl.parse(data.template, data.data); // 解析模板126. }127. 128. // 执行渲染129. thisTpl.render(data.data, function(view){130. timer(startTime);131. $('#ID-tpl-view').html(view);132. });133. });134.});135.</script>136.<p>137. 138.</body>139.</html>
API | 描述 |
---|---|
var laytpl = layui.laytpl | 获得 laytpl 模块。 |
laytpl(str, options).render(data, callback) | laytpl 组件渲染,核心方法。 |
laytpl.config(options) | 配置 laytpl 全局属性 |
laytpl(str, options).render(data, callback);
str
: 模板原始字符options
2.8+ : 当前模板实例的属性配置项。可选项详见:#属性配置data
: 模板数据callback
: 模板渲染完毕的回调函数,并返回渲染后的字符01.layui.use('laytpl', function(){02. var laytpl = layui.laytpl;03. // 直接解析字符04. laytpl('{{= d.name }}是一名前端工程师').render({05. name: '张三'06. }, function(str){07. console.log(str); // 张三是一名前端工程师08. });09. // 同步写法10. var str = laytpl('{{= d.name }}是一名前端工程师').render({11. name: '张三'12. });13. console.log(str); // 张三是一名前端工程师14.});
若模板字符较大,可存放在页面某个标签中,如:
01.<script id="TPL" type="text/html">02. <h3>{{= d.name }}</h3>03. <p>性别:{{= d.sex ? '男' : '女' }}</p>04.</script>05.<div id="view"></div>06.<!-- import layui -->07.<script>08.layui.use(function(){09. var laytpl = layui.laytpl;10. // 渲染11. var data = {12. name: '张三',13. sex: 114. };15. var getTpl = document.getElementById('TPL').innerHTML; // 获取模板字符16. var elemView = document.getElementById('view'); // 视图对象17. // 渲染并输出结果18. laytpl(getTpl).render(data, function(str){19. elemView.innerHTML = str;20. });21.});22.</script>
在实际使用时,若模板通用,而数据不同,为减少模板解析的开销,可将语句分开书写,如。
01.var compile = laytpl(str); // 模板解析02.compile.render(data, callback); // 模板渲染
标签 | 描述 |
---|---|
{{= }} |
转义输出。若字段存在 HTML,将进行转义。
|
{{- }} 2.8+ |
原始输出。若字段存在 HTML,将正常渲染。
该语句一般在需要正常渲染 HTML 时用到,但若字段存在 script 等标签,为防止 xss 问题,可采用
|
{{# }} |
JavaScript 语句。一般用于逻辑处理。
|
{{! !}} |
对一段指定的模板区域进行过滤,即不解析该区域的模板。
|
注意
开发者在使用模板语法时,需确保模板中的 JS 语句不来自于页面用户输入,即必须在页面开发者自身的可控范围内,否则请避免使用该模板引擎。
laytpl.config(options);
options
: 属性配置项。可选项详见下表属性 | 描述 |
---|---|
open | 标签符前缀 |
close | 标签符后缀 |
若模板默认的标签符与其他模板存在冲突,可通过该方法重新设置标签符,如:
01.laytpl.config({02. open: '<%',03. close: '%>'04.});05.// 模板语法将默认采用上述定义的标签符书写06.laytpl(`07. <%# var job = ["前端工程师"]; %>08. <%= d.name %>是一名<%= job[d.type] %>。09.`).render({10. name: '张三',11. type: 012.}, function(string){13. console.log(string); // 张三是一名前端工程师。14.});
若不想受到上述全局配置的影响,可在 laytpl(str, options)
方法的第二个参数中设置当前模板的局部属性,如:
01.laytpl('<%= d.name %>是一名前端工程师', {02. open: '<%',03. close: '%>'04.}).render({name: '张三'}, function(string){05. console.log(string); // 张三是一名前端工程师。06.});
Layui table 等组件的动态模板功能,均采用 laytpl 驱动。 laytpl 亦可承载单页面应用开发中的视图模板。