Template.js

xiaoxiao2021-03-01  24

template.js 一款 JavaScript 模板引擎,简单,好用。提供一套模板语法,用户可以写一个模板区块,每次根据传入的数据,生成对应数据产生的HTML片段,渲染不同的效果。https://github.com/aui/artTemplate

1、特性

(1)、性能卓越,执行速度通常是 Mustache 与 tmpl 的 20 多倍(性能测试)

(2)、支持运行时调试,可精确定位异常模板所在语句(演示)

(3)、对 NodeJS Express 友好支持

(4)、安全,默认对输出进行转义、在沙箱中运行编译后的代码(Node版本可以安全执行用户上传的模板)

(5)、支持include语句

(6)、可在浏览器端实现按路径加载模板(详情)

(7)、支持预编译,可将模板转换成为非常精简的 js 文件

(8)、模板语句简洁,无需前缀引用数据,有简洁版本与原生语法版本可选

(9)、支持所有流行的浏览器

2、语法

(1)、使用

引用简洁语法的引擎版本,例如: <script src="dist/template.js"></script> 

(2)、表达式

{{ 与 }} 符号包裹起来的语句则为模板的逻辑表达式。

(3)、输出表达式

对内容编码输出: {{content}}  不编码输出: {{#content}}  编码可以防止数据中含有 HTML 字符串,避免引起 XSS 攻击。

(4)、条件表达式

{{if admin}} <p>admin</p> {{else if code > 0}} <p>master</p> {{else}} <p>error!</p> {{/if}}

(5)、遍历表达式

      无论数组或者对象都可以用 each 进行遍历。

{{each list as value index}} <li>{{index}} - {{value.user}}</li> {{/each}}

亦可以被简写:

{{each list}} <li>{{$index}} - {{$value.user}}</li> {{/each}}

(6)、模板包含表达式

用于嵌入子模板。

{{include 'template_name'}} 

子模板默认共享当前数据,亦可以指定数据:{{include 'template_name' news_list}} 

(7)、辅助方法

使用template.helper(name, callback)注册公用辅助方法:

template.helper('dateFormat', function (date, format) { // .. return value; });

模板中使用的方式: {{time | dateFormat:'yyyy-MM-dd hh:mm:ss'}}  支持传入参数与嵌套使用: {{time | say:'cd' | ubb | link}} 

3、实例

<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>basic-demo</title> <script src="../dist/template.js"></script> </head> <body> <div id="content"></div> <script id="test" type="text/html"> {{if isAdmin}} <h1>{{title}}</h1> <ul> {{each list as value i}} <li>索引 {{i + 1}} :{{value}}</li> {{/each}} </ul> {{/if}} </script> <script> var data = { title: '基本例子', isAdmin: true, list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他'] }; var html = template('test', data); document.getElementById('content').innerHTML = html; </script> </body> </html>

<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>no escape-demo</title> <script src="../dist/template.js"></script> </head> <body> <h1>不转义HTML</h1> <div id="content"></div> <script id="test" type="text/html"> <p>不转义:{{#value}}</p> <p>默认转义: {{value}}</p> </script> <script> var data = { value: '<span style="color:#F00">hello world!</span>' }; var html = template('test', data); document.getElementById('content').innerHTML = html; </script> </body> </html>

<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>include-demo</title> <script src="../dist/template.js"></script> </head> <body> <div id="content"></div> <script id="test" type="text/html"> <h1>{{title}}</h1> {{include 'list'}} </script> <script id="list" type="text/html"> <ul> {{each list as value i}} <li>索引 {{i + 1}} :{{value}}</li> {{/each}} </ul> </script> <script> var data = { title: '嵌入子模板', list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他'] }; var html = template('test', data); document.getElementById('content').innerHTML = html; </script> </body> </html>

<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>helper-demo</title> <script src="../dist/template.js"></script> </head> <body> <h1>辅助方法</h1> <div id="content"></div> <script id="test" type="text/html"> {{time | dateFormat:'yyyy年 MM月 dd日 hh:mm:ss'}} </script> <script> /** * 对日期进行格式化, * @param date 要格式化的日期 * @param format 进行格式化的模式字符串 * 支持的模式字母有: * y:年, * M:年中的月份(1-12), * d:月份中的天(1-31), * h:小时(0-23), * m:分(0-59), * s:秒(0-59), * S:毫秒(0-999), * q:季度(1-4) * @return String * @author yanis.wang * @see http://yaniswang.com/frontend/2013/02/16/dateformat-performance/ */ template.helper('dateFormat', function (date, format) { if (typeof date === "string") { var mts = date.match(/(\/Date(\d+)\/)/); if (mts && mts.length >= 3) { date = parseInt(mts[2]); } } date = new Date(date); if (!date || date.toUTCString() == "Invalid Date") { return ""; } var map = { "M": date.getMonth() + 1, //月份 "d": date.getDate(), //日 "h": date.getHours(), //小时 "m": date.getMinutes(), //分 "s": date.getSeconds(), //秒 "q": Math.floor((date.getMonth() + 3) / 3), //季度 "S": date.getMilliseconds() //毫秒 }; format = format.replace(/([yMdhmsqS])+/g, function(all, t){ var v = map[t]; if(v !== undefined){ if(all.length > 1){ v = '0' + v; v = v.substr(v.length-2); } return v; } else if(t === 'y'){ return (date.getFullYear() + '').substr(4 - all.length); } return all; }); return format; }); // -------- var data = { time: 1408536771253, }; var html = template('test', data); document.getElementById('content').innerHTML = html; </script> </body> </html>

<div class="row"> {{each data item}} <div class="col-md-3 col-sm-4"> <div class="card card-reset"> <div class="card-header"> <h3 class="card-title">{{item.examination.examName}}</h3> <p class="examId">(考试ID:{{item.examination.examCode}})</p> <p class="exam-card-classes-count"> <!-- {{if item.examWl==0}}全科{{/if}} {{if item.examWl==1}}语文{{/if}} {{if item.examWl==2}}数学{{/if}} {{if item.examWl==3}}英语{{/if}} {{if item.examWl==4}}物理{{/if}} {{if item.examWl==5}}化学{{/if}} {{if item.examWl==6}}历史{{/if}} {{if item.examWl==7}}地理{{/if}} {{if item.examWl==8}}政治{{/if}} {{if item.examWl==9}}生物{{/if}} --> <i class="icon-group"></i>{{item.examination.grade.name}} {{item.examination.examDate | dateFormat 'yyyy-MM-dd'}}</p> </div> <div class="card-body"> {{include 'examUploadListTemplate' item}} </div> <div class="card-footer" data-id="{{item.examination.examCode}}" data-grade-nane="{{item.examination.grade.name}}"> <!-- <a onclick="SCHOOL.onClickSchsScore(this)"><i class="iconfont icon-tuichu mb-1"></i> 总分</a> --> <a onclick="SCHOOL.onClickSchsDetails(this)"><i class="iconfont icon-tuichu mb-1"></i> 分数</a> <a onclick="SCHOOL.onClickSchsSelect(this)"><i class="iconfont icon-tuichu mb-1"></i> 客观题</a> <a onclick="SCHOOL.onClickSchsAnswer(this)"><i class="iconfont icon-tuichu mb-1"></i> 调分</a> <a onclick="SCHOOL.onClickSchsAnalysis(this)"><i class="iconfont icon-xueshengduantongji mb-1"></i> 分析</a> <a onclick="SCHOOL.onClickSchsClear(this)"><i class="iconfont icon-shanchu mb-1"></i> 清空</a> </div> </div> </div> {{/each}} </div> </script> <script type="text/plain" id="examUploadListTemplate"> <ul class="anly-xk"> {{each examinationStatus item}} {{if item.analyzeStatus == 1}}<img class="is-anly" src="../assets/img/pass.png"> {{/if}} {{if examinationStatus.length < 3}} <li class="li-lg" title="{{item.paper.paperName}}"> <svg width="100%" height="100%" viewBox="0 0 200 200"> <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.detailScoreStatus == 1}} stroke="#FF3852" {{else}} stroke="#ccc" {{/if}} {{if item.paper.itemStatus == true}} fill="#428BCA" {{else}} fill="#fff" {{/if}} ></circle> <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.totalScoreStatus == 1}} stroke="#60CF66" {{else}} stroke="#ccc" {{/if}} fill="none" stroke-dasharray="310"></circle> <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.answerStatus == 1}} stroke="#F79B04" {{else}} stroke="#ccc" {{/if}} fill="none" stroke-dasharray="160 400"></circle> <text x="50%" y="50%" dy=".3em" {{if item.paper.itemStatus == true}} fill="#fff" {{else}} fill="#000" {{/if}} font-size="50">{{item.paper.subject.name}}</text> </svg></li> {{else}}<li title="{{item.paper.paperName}}"><svg width="100%" height="100%" viewBox="0 0 200 200"> <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.detailScoreStatus == 1}} stroke="#FF3852" {{else}} stroke="#ccc" {{/if}} {{if item.paper.itemStatus == true}} fill="#428BCA" {{else}} fill="#fff" {{/if}} ></circle> <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.totalScoreStatus == 1}} stroke="#60CF66" {{else}} stroke="#ccc" {{/if}} fill="none" stroke-dasharray="310"></circle> <circle cx="100" cy="100" r="75" stroke-width="30" {{if item.answerStatus == 1}} stroke="#F79B04" {{else}} stroke="#ccc" {{/if}} fill="none" stroke-dasharray="160 400"></circle> <text x="50%" y="50%" dy=".3em" {{if item.paper.itemStatus == true}} fill="#fff" {{else}} fill="#000" {{/if}} font-size="50">{{item.paper.subject.name}}</text> </svg></li>{{/if}} {{/each}} </ul> </script> <!-- 导入 --> <script type="text/plain" id="schImportDataTemplaet"> <div class="form-group"> <select class="form-control form-control-sm" id="subject"> {{each examinationStatus item}} <option value="{{item.paper.paperCode}}">{{item.paper.subject.name}} {{item.paper.paperName}}</option> {{/each}} </select> </div> <div class="form-files"> <div id="error_info"></div> <input type="file" id="import_excel" name="file" class="dropify-fr" data-default-file="" multiple="multiple" accept="application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /> </div> </script> <!-- 考试分析 --> <script type="text/plain" id="schAnalysisTemplate"> <p class="mb-3">请选择您要进行考试分析的学科</p> <div class="form-group text-left" id="schAnySubject"> <div class="form-check mb-2"> <input class="form-check-input" type="checkbox" id="schAllAny" style="top: -5px;"> <label class="form-check-label" for="schAllAny">全选</label> </div> {{each examinationStatus item}} <div class="form-check mb-1"> <input class="form-check-input" type="checkbox" name="subjects" id="subjectChickbox{{item.paper.paperCode}}" value="{{item.paper.paperCode}}" style="top: -5px;"> <label class="form-check-label" for="subjectChickbox{{item.paper.paperCode}}">{{item.paper.subject.name}}</label> <p class="float-right">{{item.paper.paperName}}</p> </div> {{/each}} </div> </script> <!-- 清空 --> <script type="text/plain" id="schClearTemplaet"> <div class="form-group" id = "clearZT"> <div class="form-check form-check-inline"> <input class="form-check-input" type="checkbox" name="ZT" value="1" id="schClear1"> <label class="form-check-label" for="schClear1">清空导入数据</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="checkbox" name="ZT" value="2" id="schClear2"> <label class="form-check-label" for="schClear2">清空分析结果</label> </div> </div> <hr> <div class="form-group" id="schClearSubject"> <div class="form-check mb-2"> <input class="form-check-input" type="checkbox" id="schAllClear" style="top: -5px;"> <label class="form-check-label" for="schAllClear">全选</label> </div> {{each examinationStatus item}} <div class="form-check mb-1"> <input class="form-check-input" type="checkbox" name="subjects" id="subjectChickbox{{item.paper.paperCode}}" value="{{item.paper.paperCode}}" style="top: -5px;"> <label class="form-check-label" for="subjectChickbox{{item.paper.paperCode}}">{{item.paper.subject.name}}</label> <p class="float-right">{{item.paper.paperName}}</p> </div> {{/each}} </div> </script> initSchsSelect : function(srtId, isChecked) { let id = parseInt(srtId); let schsArr = SCHOOL.getSchsArr(); let subjectObj = {}, subjectArr = []; for (let i = 0; i < schsArr.length; i++) { if (id == schsArr[i].examination.examCode) { subjectArr = schsArr[i].examinationStatus; } }; subjectObj.examinationStatus = subjectArr; if (isChecked) { document.getElementById('schAnalysisHtml').innerHTML = template('schAnalysisTemplate', subjectObj); } else { document.getElementById('schImportDataHtml').innerHTML = template('schImportDataTemplaet', subjectObj); Men.dropify(); } } }

 

 

 

 

 

 

 

 

 

 

 

 

 

转载请注明原文地址: https://www.6miu.com/read-4150179.html

最新回复(0)