模板技术
模板技术的诞生是为了将显示与数据分离,模板技术多种多样,但其本质是将模板文件和数据通过模板引擎生成最终的文件内容。
模板技术原理
模板技术并不是什么神秘技术,干的是拼接字符串的体力活。模板引擎就是利用正则表达式识别模板标识,并利用数据替换其中的标识符。
模板技术包含两个方面:
- 定义模板标识符
- 解析模板标识符
代码举例:
//字符串替换的思想
function tmpl(str, obj) { // 解析模板标识
if (typeof str === 'string') {
return str.replace(/<%=\s*([^%>]+)\s*%>/g, function() {
let key = arguments[1];
return obj[key];
});
}
}
let str = "Hello, <%= name%>"; // 模板内容
let obj = {name: "树先生"}; // 模板数据
console.log(tmp(str, obj))
常用模板技术
模板技术:Pug、Mustache、EJS、Handlebars,国内的有 baiduTemplate(百度)、artTemplate(腾讯)、juicer(淘宝)。
EJS 使用
使用之前需安装包:
npm install ejs
1)常用标签
<%= 输出数据到模板(输出是转义 HTML 标签)
<%- 输出非转义的数据到模板
<% 用于流程控制,无输出
%> 一般结束标签
2)用法
const ejs = require('ejs');
ejs.render(str, data, options); // => 输出绘制后的 HTML字符串
ejs.renderFile(filename, data, options, function(err, str){ // str => 输出绘制后的 HTML字符串
});
- cache 缓存编译后的函数,需要提供 filename
- filename 被 cache 参数用做键值,同时也用于 include 语句
- context 函数执行时的上下文环境
- compileDebug 当为 false 时不编译调试语句
- client 返回独立的编译后的函数
- delimiter 放在角括号中的字符,用于标记标签的开与闭
- debug 将生成的函数体输出
- _with 是否使用 with() {} 结构。如果为 false,所有局部数据将存储在 locals 对象上。
- localsName 如果不使用 with ,localsName 将作为存储局部变量的对象的名称。默认名称是 locals
- rmWhitespace 删除所有可安全删除的空白字符,包括开始与结尾处的空格。对于所有标签来说,它提供了一个更安全版本的 -%> (在一行的中间并不会剔除标签后面的换行符)
- escape 为 <%= 结构设置对应的转义(escape)函数。它被用于输出结果以及在生成的客户端函数中通过 .toString() 输出。(默认转义 XML)
3)输出
// 模板文件 out.ejs
<h2><%= user.name %></h2>
<h2><%- user.name %></h2>
const ejs = require('ejs');
ejs.renderFile(__dirname + '/out.ejs', {user : {name : '<span>lony</span>'}}, (err, str) => {
// str => 输出绘制后的 HTML 字符串
console.log(str);
});
4)条件
// 模板文件 if.ejs
<% if (user) { %>
<h2><%= user.name %></h2>
<% } %>
const ejs = require('ejs');
ejs.renderFile(__dirname + '/if.ejs', {user : {name : 'lony'}}, (err, str) => {
console.log(str);
});
5)循环
// 模板文件 loop.ejs
<% users.forEach((user) => { %>
<%= user.id %> <%= user.name %>
<% }) %>
const ejs = require('ejs');
ejs.renderFile(__dirname + '/loop.ejs', {users : [{id : 1, name: 'xx'}, {id : 2, name: 'yy'}]}, (err, str) => {
console.log(str);
});
使用模板技术响应 HTML
// books.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>书籍</title>
</head>
<body>
<ul>
<% books.forEach((book) => { %>
<li><%= book %></li>
<% }) %>
</ul>
</body>
</html>
const http = require('http');
const ejs = require('ejs');
// 使用模板技术响应 HTML 格式的数据
http.createServer((req, res) => {
res.writeHead(200, {'Content-Type' : 'text/html'});
let data = {books: ['西游记', '三国演义', '水浒传', '红楼梦']};
ejs.renderFile(__dirname + '/books.ejs', data, (err, str) => {
console.log(str);
res.end(str);
});
}).listen(8888);