前言
大家想到的模板引擎有哪些?
template,handlebars, jade, ejs, underscore, nunjunks…
vue里面也有template的概念
ejs 通过<%%> 包起来用
vue通过{{}}来使用
我们今天也来整个玩玩
实现
我们先来理下思路:
1、 模板里面的变量是如何替换的
2、 模板里面的内容是如何传参的
我们这边以{% %}方式来做吧
我们先来写个简单的吧
template模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>字符串模板</title>
</head>
<body>
{%if(true){%}
hello
{%} else {%}
world
{% } %}
</body>
</html>
js模块实现:
const fs = require('fs');
let template = fs.readFileSync('./template-simple.html','utf8');
const wrapperContent = [
'let str = "";\r\nstr+=`',
'`;\r\nreturn str;\r\n'
];
function render(templateStr, obj) {
templateStr = templateStr.replace(/\{\%(.+?)\%\}/g,function(){
return '`\r\n'+arguments[1]+'\r\nstr+=`'
});
let fnContent = wrapperContent[0]+templateStr+wrapperContent[1];
let newFn = new Function(fnContent);
return newFn(obj);
}
const r = render(template);
console.log(r);
运行结果看一波
上面的内容我们来总结下:
1、 我们先把模板文件内容读取出来
2、 列出固定头固定尾 我们后续会使用字符串拼接
3、 写一个render函数,学习ejs一把 里面是具体的转换内容
4、 render函数内部主要是通过正则去替换掉{% %}模板标识符
5、 最重要的一点是new Function函数,去创造了一个函数,返回了转换好的字符串
那么有人会说了,模板字符串肯定要传参的呀
那我们来咯~
模板页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>字符串模板</title>
</head>
<body>
{%if(true){%}
hello
{%} else {%}
world
{% } %}
<ul>
{% arr.forEach(item => { %}
<li>{{item}}</li>
{%})%}
</ul>
</body>
</html>
js模块:
const fs = require('fs');
let template = fs.readFileSync('./template.html','utf8');
// with是申明了一块作用域,可以通过传参给作用域里面使用
const wrapperContent = [
'let str = "";\r\nwith(val){\r\nstr+=`',
'`;}\r\nreturn str;\r\n'
];
function render(templateStr, obj) {
// 替换模板标识符
templateStr = template.replace(/\{\{(.+?)\}\}/g, function(){
return '${'+ arguments[1] +'}';
});
// 替换掉模板中的变量
templateStr = templateStr.replace(/\{\%(.+?)\%\}/g,function(){
return '`\r\n'+arguments[1]+'\r\nstr+=`'
});
let fnContent = wrapperContent[0]+templateStr+wrapperContent[1];
let newFn = new Function('val',fnContent);
return newFn(obj);
}
const r = render(template, {arr: [1,2,3]});
console.log(r);
with的使用可以参考 看下效果
那么一个简单的模板引擎已经出来了
我们总结下:
1、 我们在模板html里面采用ejs的写法来配置模板
2、 new Function 这边添加传参,添加with创造作用域,支持替换变量使用
3、 render函数将变量模块(本处使用{{}}包住)替换成模板字符串的${}方式,模板字符串会做处理