模板引擎,“ 引擎 ” 两字一直让我觉得其高大上,今天要好好梳理
以一个例子证明其用处:点击按钮发送 ajax 请求获取后台服务器数据,再将数据显示在网页的空 table标签 中
Node 实现的小服务器
var http = require('http')
var server = http.createServer()
server.on('request', function (req, res) {
res.setHeader('Access-Control-Allow-Origin','*') //跨域资源共享,允许任何源的请求
//json数组,模拟数据库数据
var data = `[{
"name": "MicKong",
"age": "20",
"sex":"male",
"tel":"123456",
"address":"Beijing"
},
{
"name": "May",
"age": "18",
"sex":"female",
"tel":"123456",
"address":"Hong Kong"
}]`
res.end(data) //响应data数据
})
server.listen(3000, function () {
console.log('Server running...')
})
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table id="list"></table> <!--将数据显示在这个空的table标签中-->
<input type="button" id="btn" value="获取数据">
<script>
document.getElementById('btn').onclick = function () {
var xhr = new XMLHttpRequest()
xhr.open('get', 'http://127.0.0.1:3000')
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return
console.log(JSON.parse(xhr.responseText)); //先输出到控制台看是否成功获取到了数据
}
}
</script>
</body>
</html>
浏览器成功获取到数据
接下来数据不是要输出到控制台而是通过DOM操作直接显示到当前网页
xhr.onreadystatechange = function () { if (xhr.readyState !== 4) return var data = JSON.parse(xhr.responseText); var table = document.getElementById('list') for (var i = 0; i < data.length; i++) { var tr = document.createElement('tr') var td1 = document.createElement('td') td1.innerHTML = data[i].name tr.appendChild(td1) var td2 = document.createElement('td') td2.innerHTML = data[i].age tr.appendChild(td2) var td3 = document.createElement('td') td3.innerHTML = data[i].sex tr.appendChild(td3) /* 略...... */ table.appendChild(tr) } document.body.appendChild(table) }
DOM 操作时创建行再创建列,列添加到行中,行添加到表格......可以看到数据的渲染十分繁琐,更别说数据多的时候,当然可以使用 for...in 和 tr.innerHTML = '<td></td>' 的方式,但这仍不够轻松便捷。此时可使用模板引擎,帮我们完成数据的渲染
模版引擎实际上就是一个 api,本质就是字符串解析替换。模版引擎有很多种,使用方式大同小异,目的为了更容易地将数据渲染到 html 中
这里使用 art-template 模板引擎,可以在 github 下载也可用 npm 下载
该命令会下载到当前目录,下载后会有 node_modules 文件夹,node_modules/art-template/lib/template-web.js
node_modules 文件夹不要改动
使用步骤
❶ 下载后用 script 标签将模板引擎引入到 html 中
❷ 准备一个模板
❸ 准备一个数据
❹ 通过模板引擎提供的一个函数将模板和数据整合得到渲染结果 html
❺ 将渲染结果的 html 设置到默认元素的 innerHTML 中
引入 template-web.js 并准备一个模板,根据 template-web.js文档 里的语法创建模板
<script src="template-web.js"></script> <!-- 引入template-web.js -->
<script id="temp" type="text/x-template-web"> <!--each内部的$value拿到的是当前被遍历的元素-->
{{each target}}
<tr>
<td>{{ $value.name }}</td>
<td>{{ $value.age }}</td>
<td>{{ $value.sex }}</td>
<td>{{ $value.tel }}</td>
<td>{{ $value.address }}</td>
</tr>
{{/each}}
</script>
模板可以作为字符串放在 js 里,也可写在 table 标签内 ,甚至 div 中,之所以放在 script标签 里,是因为 script标签 的 type 如果不为 " text/javascript " 的话就不会当作 js 代码执行,标签里的内容不但能换行又有着色显示,还不会显示到网页中,是个很好的模板存放地。type 值为只要不为 " text/javascript " 即可,x是自定义的意思,后面跟上所用的模板引擎名字,这样写仅是为了见名知意
准备数据,用模板引擎的API将模板和数据整合,并将结果赋值给想要渲染元素的 innerHTML
template( ' script标签的id ' , {对象} )
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return
var data = JSON.parse(xhr.responseText)
//模板所需的数据
var content = {target: data} //target名可随意,但要与模板里each循环名字一致
//借助模板引擎的API渲染数据
var result = template('temp', content) //通过模板引擎提供的一个函数将模板和数据整合得到渲染结果 html
document.getElementById('list').innerHTML = result //将渲染结果的html设置到table的innerHTML中
}
点击按钮,ajax 获取数据后利用 art-template 成功将数据渲染到网页中
模板引擎只关心自己能认识的模板标记语法
如 {{ }} ,其他内容则不会改动
<script id="temp" type="text/x-template-web">
大家好我叫{{ name }}
今年{{ age }}岁
喜欢{{each hobby}} {{ $value }} {{/each}}
</script>
<script>
//template函数放入模板和数据
var result = template('temp', {
name: 'Paul',
age: 20,
hobby: ['fruits','songs','sports']
})
console.log(result)
</script>
Node 中使用模板引擎
模板引擎最早就是诞生于服务器领域,后来才发展到了前端。art-template 是个 js模板引擎,不但可在浏览器中使用,也可在 Node 中使用
❶ 安装 npm install art-template,npm安装好后才能在代码中用 require() 加载
❷ 在需要使用的文件模块中加载 art-template
❸ 查文档,使用模板引擎的API
template.render ( ' 模板字符串 ' ,{对象} )
var template = require('art-template')
var result = template.render('hello {{ name }}',{
name:'Paul'
})
console.log(result)
接下来要在 html 中编写模板语法(也就是把整个 html 作为上面的 ‘ 模板字符串 ’ ),在服务端渲染后再响应给浏览器
demo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<h3>{{ title }}</h3>
<ul>
<li>姓名:{{ name }}</li>
<li>年龄:{{ age }}</li>
<li>爱好:{{each hobby}} {{ $value }} {{/each}}</li>
</ul>
<script>
var str = '{{ title }}' //在字符串内模版引擎依旧能识别{{}}
</script>
</body>
</html>
后台读取 demo.html 文件,通过 template模块的 render() 方法将模板和数据整合并返回给浏览器
var http = require('http') //http模块创建服务器
var template = require('art-template') //加载art-template模块
var fs = require('fs') //加载fs模块,为了读取文件
var server = http.createServer()
server.on('request', function (req, res) {
fs.readFile('./demo.html',function (err,data) {
if(err)
return res.end('Can not find demo.html')
//读取的文件内容是二进制,但render要的是字符串
var result = template.render(data.toString(),{
name:'Paul',
age: 20,
hobby:['songs','sports','food'],
title:'个人信息'
})
res.end(result)
})
})
server.listen(3000, function () {
console.log('Server running...')
})
浏览器访问,直接拿到渲染后的结果
如果是客户端异步请求后渲染的,右键查看源代码则找不到相关内容,如果在页面源代码中找得到的就是服务端渲染的
客户端渲染不利于 SEO 搜索引擎优化但速度快用户体验友好,服务端渲染可被爬虫抓取,客户端异步渲染很难被爬虫抓取,所以真正的网站是两者结合来做的