HTML 模板到 Javascript 字符串文字
HTML template to Javascript String Literals
感谢任何反馈...
我有一个 HTML 模板,其中嵌入了 JS 字符串文字...
<html>
<head>
<title>${title}</title>
</head>
<body>
User name: ${user.name}
</body>
</html>
然后我在做...
let temp = require('./template.html')
return temp; // <--- I need this to return the compiled html
如何获取要呈现的字符串文字?
甚至可以这样做吗?
我需要将 'temp' 变量作为编译后的字符串 return,以便稍后在代码中将其插入 document.write。
谢谢。
您可以创建一个新的Function将其变成字符串模板
return new Function("title","user","return `" + temp + "`;")(title,user);
正如 T.J 所指出的,您需要了解模板中使用的所有变量并将它们作为函数的参数包含在内。
是的,可以对您的代码进行一些小的修改。
先将template.html
重命名为template.js
并将其内容改为
exports default ({title, user}) =>`
<html>
<head>
<title>${title}</title>
</head>
<body>
User name: ${user.name}
</body>
</html>`
然后 let temp = require('./template.js')
将为 temp 分配一个函数,您应该根据上下文调用该函数。像
let ctx = { title: 'titre', user: { name: 'alice' } }
let compiled = temp(ctx) // your compiled template
查看yo-yo 围绕此概念工作的库
那些不是字符串文字。它们看起来像 JavaScript 的模板文字中的标记。
Is it even possible to do this?
如果您的意思是要动态加载 HTML 然后将其用作模板文字,那么您只有两种选择:
使用模板库(或编写您自己的模板代码)解析字符串并处理这些标记
使用eval
/ new Function
eval
(或 new Function
)并不邪恶 当与您自己的内容一起使用时(并且性能成本非常 夸大了),虽然我并不是说我会推荐它。但这就是你要做的(假设在你的堆栈中,require('./template.html')
会给你一个包含内容的字符串):
let temp = require('./template.html');
const template = "`" + temp.replace(/`/g, "\`") + "`";
(这里可能还有更多转义,我只是处理了反引号。)
然后当您在范围内有相关标记时:
const str = eval(template);
实例:
let temp = document.getElementById("template").textContent.trim();
const template = "`" + temp.replace(/`/g, "\`") + "`";
// Using it
const title = "This is the title";
const user = {name: "Joe Blogs"};
const str = eval(template);
console.log(str);
<script type="text/template" id="template">
<html>
<head>
<title>${title}</title>
</head>
<body>
User name: ${user.name}
</body>
</html>
</script>
为什么上面的 eval
而不是 new Function
?因此,包装模板以供使用的代码不必知道名称 title
和 user
。 new Function
仍然允许任意代码执行,就像 eval
一样,所以除了您自己的内容之外,您仍然不能使用它...
感谢任何反馈...
我有一个 HTML 模板,其中嵌入了 JS 字符串文字...
<html>
<head>
<title>${title}</title>
</head>
<body>
User name: ${user.name}
</body>
</html>
然后我在做...
let temp = require('./template.html')
return temp; // <--- I need this to return the compiled html
如何获取要呈现的字符串文字?
甚至可以这样做吗?
我需要将 'temp' 变量作为编译后的字符串 return,以便稍后在代码中将其插入 document.write。
谢谢。
您可以创建一个新的Function将其变成字符串模板
return new Function("title","user","return `" + temp + "`;")(title,user);
正如 T.J 所指出的,您需要了解模板中使用的所有变量并将它们作为函数的参数包含在内。
是的,可以对您的代码进行一些小的修改。
先将template.html
重命名为template.js
并将其内容改为
exports default ({title, user}) =>`
<html>
<head>
<title>${title}</title>
</head>
<body>
User name: ${user.name}
</body>
</html>`
然后 let temp = require('./template.js')
将为 temp 分配一个函数,您应该根据上下文调用该函数。像
let ctx = { title: 'titre', user: { name: 'alice' } }
let compiled = temp(ctx) // your compiled template
查看yo-yo 围绕此概念工作的库
那些不是字符串文字。它们看起来像 JavaScript 的模板文字中的标记。
Is it even possible to do this?
如果您的意思是要动态加载 HTML 然后将其用作模板文字,那么您只有两种选择:
使用模板库(或编写您自己的模板代码)解析字符串并处理这些标记
使用
eval
/new Function
eval
(或 new Function
)并不邪恶 当与您自己的内容一起使用时(并且性能成本非常 夸大了),虽然我并不是说我会推荐它。但这就是你要做的(假设在你的堆栈中,require('./template.html')
会给你一个包含内容的字符串):
let temp = require('./template.html');
const template = "`" + temp.replace(/`/g, "\`") + "`";
(这里可能还有更多转义,我只是处理了反引号。)
然后当您在范围内有相关标记时:
const str = eval(template);
实例:
let temp = document.getElementById("template").textContent.trim();
const template = "`" + temp.replace(/`/g, "\`") + "`";
// Using it
const title = "This is the title";
const user = {name: "Joe Blogs"};
const str = eval(template);
console.log(str);
<script type="text/template" id="template">
<html>
<head>
<title>${title}</title>
</head>
<body>
User name: ${user.name}
</body>
</html>
</script>
为什么上面的 eval
而不是 new Function
?因此,包装模板以供使用的代码不必知道名称 title
和 user
。 new Function
仍然允许任意代码执行,就像 eval
一样,所以除了您自己的内容之外,您仍然不能使用它...