在express里帮我们集成了ejs模版引擎,引入他之后可以直接用ejs,第一步安装
模版引擎的应用
ejs.js
let express = require('express');
let app = express();
let path = require('path');
app.engine('html' , require('ejs').__express);//让html以ejs形式渲染
app.set('view engine', 'html')
//设置试图查找路径
app.set('views' , path.resolve(__dirname))
app.get('/',function(req,res){ //类型默认jade && ejs
res.render('1',{title:'hello', arr:[1,2,3,4]})
})
app.listen(3000)
复制代码
1.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
<script src="main.js"></script>
</head>
<body>
<%=title%>
<%arr.forEach(item=>{%>
<li><%=item%></li>
<%})%>
</body>
</html>
复制代码
模版引擎的实现
解析简单对象
<body>
<li><%=name%></li>
<li><%=age%></li>
</body>
复制代码
let fs = require('fs');
let result = fs.readFileSync(__dirname+'/case1.html','utf8');
let school = {name:'zdl',age:9};
function render(str,obj) {
return str.replace(/<%=([\s\S]*?)%>/g,function () {
return obj[arguments[1]] //查找并替换
})
}
console.log(render(result, school));
复制代码
解析if-else
<body>
<%if(title === 'hello'){%>
hello world
<%}else{%>
world
<%}%>
</body>
复制代码
let fs = require('fs');
let result = fs.readFileSync(__dirname +'/1.html','utf8');
let json = {title:'hello'}
function render(obj){
let content;
let head = "let templ = '';\n";
head += "with(obj){\ntempl+=`" ;//将obj作为作用域,执行函数
content = obj.replace(/<%([\s\S]*?)%>/g,function(){
return "`\n" + arguments[1] + "\ntempl+=`"
})
let end = "`}\n return templ;"
return head + content + end;
}
let r = render(result);
let fn = new Function("obj",r) //通过fn将拼接好的r字符串执行
let str = fn(json)
console.log(str);
复制代码
拼接出的r
let templ = '';
with(obj){
templ+=`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
<script src="main.js"></script>
</head>
<body>`
if(title === 'hello'){
templ +=`hello world`
}else{
templ+=`world`
}
templ+=`
</body>
</html>`
}
return templ;
复制代码
将r用函数包起来,实例化执行,得到的templ就是所得到的r里函数执行后的值
Function("obj",r){
let templ = '';
with(obj){
templ += ...
}
return templ;
}
复制代码
with的作用生将当前javascritpt的内容,以obj作为作用域(上下文)执行,同样道理当我们遇到如下
解析forEach
<body>
<%arr.forEach(item=>{%>
<li>item</li>
<%})%></body>
复制代码
结合上述两种方法我们简单的模版引擎就完成了
let fs = require('fs');
let result = fs.readFileSync(__dirname +'/1.html','utf8');
let json = {title:'hello', arr:[1,2,3,4]}
function render(obj){
let content;
// content = obj.replace(/<%=([\s\S]*?)%>/g,function(){
// return obj[arguments[1]]
// })
//执行 eval new function
let head = "let templ = '';\n";
head += "with(obj){\ntempl+=`" ;//将obj作为作用域,执行函数
content = obj.replace(/<%=([\s\S]+?)%>/g,function () {
return '${'+arguments[1]+'}';
});
content = content.replace(/<%([\s\S]*?)%>/g,function(){
return "`\n" + arguments[1] + "\ntempl+=`"
})
let end = "`}\n return templ;"
return head + content + end;
}
let r = render(result);
let fn = new Function("obj",r)
let str = fn(json)
console.log(str);
复制代码
将js以中间件的形式存在ejs.js文件中
ejs.js
let express = require('express');
let app = express();
let path = require('path');
app.engine('html' , require('ejs').__express);//让html以ejs形式渲染
app.set('view engine', 'html')
//设置试图查找路径
app.set('views' , path.resolve(__dirname));
app.use(function(res,req,next){
function render(obj){
let content;
let head = "let templ = '';\n";
head += "with(obj){\ntempl+=`" ;//将obj作为作用域,执行函数
content = obj.replace(/<%=([\s\S]+?)%>/g,function () {
return '${'+arguments[1]+'}';
});
content = content.replace(/<%([\s\S]*?)%>/g,function(){
return "`\n" + arguments[1] + "\ntempl+=`"
})
let end = "`}\n return templ;"
return head + content + end;
}
res.render = function(filename,data){
let p = app.get('views');
let file = filename + '.' + app.get('view engine');
let filepath = path.join(p,file);
require('fs').readFileSync(filepath,'utf8');
let fn = new Function('data',render(result))
res.end(fn(data));
}
next();
})
app.get('/',function(req,res){ //类型默认jade && ejs
res.render('1',{title:'hello', arr:[1,2,3,4]})
})
app.listen(3000)
复制代码
test: localhist:3000测试