渲染UI结构时遇到的问题
通过字符拼接或依次改变dom内容的形式el.html(值)来渲染结构比较复杂,维护也很麻烦
<script>
// 使用jQuery提供的JSONP方法
$.ajax({
dataType:'jsonp',//如果发送JSONP请求,必须指定这一项
url:'http://localhost:3000/api/jsonp',
success:function(res){
console.log(res);
// 渲染dom结构
var rows = []
$.each(res.data, function (i, item) {
rows.push('<li class="list-group-item"> ' + item.a + '</li>')
})
$('#cmt-list').empty().append(rows.join(''))
}
})
</script>
模板引擎
模板引擎:可以根据程序员指定的模板结构和数据,自动生成一个完整的HTML页面
优点: 结构清晰,减少字符串拼接,代码易于阅读和维护
art-template
官网
art-template是一个简约、超快的模板引擎
使用步骤
- 导入
<script src="./js/template-web.js"></script>
- 定义数据
[{ name: 'zs' }]
- 定义模板
<script type="text/html" id="search-list">
<h1>{{name}}</h1>
</script>
- 调用 template 函数来渲染dom
let htmlStr=template('search-list', { name: 'zs' })
$('div').html(htmlStr)
标准语法
art-template提供了 {{}} 这种语法格式,在{{}}内可以进行变量输出,或循环数组等操作,这种{{}} 语法在art-template 中被称为标准语法。
输出
//在{{}}语法中,可以输出变量、对象属性、三元表达式、逻辑或、加减乘除等
{{value}}
{{obj.key}}
{{obj['key'}}
{{a?b:c}}
原文输出
//如果要输出的value值中,包含了HTML标签结构,则需要使用原文输出语法,才能保证HTML标签被正常渲染
{{@ value}}
//如果数据是
{ test:<h1>h1</h1> }
//要想通过模版渲染出来
<script type="text/html" id="search-list">
<h1>{{@ test}}</h1>
</script>
条件输出
//如果需要实现条件输出,则可以在{{}}中使用if...else if.../if的方式,进行按需输出
{{if value}} 按需输出的内容 {{/if}}
{{if v1}} 按需输出的内容 {{else if v2}} 按需输出的内容 {{/if}}
<!-- 模版 -->
<script type="text/html" id="search-list">
{{if test==1}}test==1
{{else}}test!=1{{/if}}
</script>
<!-- 调用 template 函数来渲染dom -->
<script>
let htmlStr=template('search-list', { test: 0 })
$('div').html(htmlStr)
</script>
循环输出
通过each语法循环数组,当前循环的缩影使用 value 进行访问
{{each arr}}
{{$index}}{{$value}}
{{/each}}
<!-- 模版 -->
<script type="text/html" id="search-list">
{{each arr}}
{{$index}}{{$value.test}}
{{/each}}
</script>
<!-- 调用 template 函数来渲染dom -->
<script>
//传入的数据至少是在对象里,也就是被{}包住
let htmlStr=template('search-list', { arr: [{ test: 0 }, { test: 1 }] })
$('div').html(htmlStr)
</script>
过滤器
过滤器的本质就是一个函数,处理一些参数返回需要的值
//定义过滤器
template.defaults.imports.filterName=function(value){/*return处理的结果*/}
//使用
{{value(需要处理的值,传入处理函数中)|filterName(处理函数)}}
<!-- 模版 -->
<script type="text/html" id="search-list">
{{each arr}}
{{$index}}{{$value.test|filterName}}
{{/each}}
<!-- 结果 02 12 -->
</script>
<!-- 调用 template 函数来渲染dom -->
<script>
template.defaults.imports.filterName = function (value) {
console.log(value);
value=2;
return value
}
let htmlStr=template('search-list', { arr: [{ test: 0 }, { test: 1 }] })
// console.log(htmlStr);
$('div').html(htmlStr)
</script>
实现简易的模版引擎
实现步骤
- 定义模版结构
<script type="text/html" id="tpl-user">
<div>姓名:{{name}}</div>
<div>年龄:{{age}}</div>
<div>性别:{{gender}}</div>
<div>住址:{{address}}</div>
</script>
- 预调用模板引擎
<script>
// 定义数据
let data={
name:'zs',
age:23,
gender:'男',
address:'北京'
}
// 调用模板函数
let htmlStr=template('tpl-user',data)
console.log(htmlStr);
/* 打印结果
<div>姓名:zs</div>
<div>年龄:23</div>
<div>性别:男</div>
<div>住址:北京</div>
*/
// 渲染HTML结构
document.getElementById('user-box').innerHTML=htmlStr
</script>
- 封装 template 函数
<script>
function template(id,data){
let str=document.getElementById(id).innerHTML
let pattern=/{{\s*([a-zA-Z]+)\s*}}/
let patternResult=null
while((patternResult=pattern.exec(str))){
str=str.replace(patternResult[0],data[patternResult[1]])
}
return str
}
</script>
- 导入并使用自定义的模版引擎