实现ejs类似的功能,模板引擎。
转换效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>模板引擎</title>
</head>
<body>
<ul id="name_list"></ul>
<script type="text/html" id="user_tmpl">
<%for ( var i = 0; i < users.length; i++ ) { %>
<li>
<a href="<%=users[i].url%>"> <%=users[i].name%> </a>
</li>
<% } %>
</script>
<script src="index.js"></script>
</body>
</html>
- 针对上述的代码实现模板引擎,让其转换为真正的html。需要转换的部分如下:
想要实现的效果如下:<script type="text/html" id="user_tmpl">
<%for ( var i = 0; i < users.length; i++ ) { %>
<li>
<a href="<%=users[i].url%>"> <%=users[i].name%> </a>
</li>
<% } %>
</script>
let str = ``
with (data) {
str += `
`
for (var i = 0; i < users.length; i++) {
str += `
<li>
<a href="${users[i].url}"> ${users[i].name} </a>
</li>
`
}
str += `
`
}
return str
实现方案
/**
* @author lihh
* @description 实现模板引擎 其实就是把无用的变量内容替换为字符串
* @param {*} str 传递的字符串
* @param {*} data 渲染的数据
* @returns
*/
function tmpl(str, data) {
// 1. 将<%=XXX%> 替换为${XXX}
str = str.replace(/<%=(.*?)%>/gi, '${$1}')
// 2. 用变量str进行拼接,用with限定作用域
let string = 'let str = ``; \r\n with(data){'
string += 'str += `'
// 3. 以<%XXX%> 为界限进行分割,进行字符串的拼接
string += str.replace(/<%(.+?)%>/gi, function () {
return '`\r\n' + arguments[1] + '\r\n str += `'
})
string += '` \r\n } \r\n return str'
// 4. new Function 来运行字符串
const fn = new Function('data', string)
return fn(data)
}