标签模板及其应用
2019-12-03 本文已影响0人
me_coder
1、标签模板
标签模板其实不是模板,而是函数调用的一种特殊形式。“标签”指的就是数,紧跟在后面的模板字符串就是它的参数。
但是,如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。
例如:
let a = 5;
let b = 10;
tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);
下面给出一个示例代码及其运行结果:
let a = 5;
let b = 10;
function tag(s, v1, v2) {
console.log(s[0]);
console.log(s[1]);
console.log(s[2]);
console.log(v1);
console.log(v2);
return "OK";
}
tag`Hello ${ a + b } world ${ a * b}`;
// "Hello "
// " world "
// ""
// 15
// 50
// "OK"
一个复杂的例子:
let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;
function passthru(literals) {
let result = '';
let i = 0;
while (i < literals.length) {
result += literals[i++];
if (i < arguments.length) {
result += arguments[i];
}
}
return result;
}
msg // "The total is 30 (31.5 with tax)"
对这个例子写成如下分析代码:
let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;
function passthru(literals) {
let result = '';
let i = 0;
while (i < literals.length) {
console.log(i,'literals',literals[i++]);
if (i < arguments.length) {
console.log(i,'arguments',arguments[i]);
}
}
return result;
} ;
msg
得到结果为:
0 literals The total is
1 arguments 30
1 literals (
2 arguments 31.5
2 literals with tax)
采用rest参数写法如下:
function passthru(literals, ...values) {
let output = "";
let index;
for (index = 0; index < values.length; index++) {
output += literals[index] + values[index];
}
output += literals[index]
return output;
}
对其进行分析:
let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;
function passthru(literals, ...values) {
let output = "";
let index;
for (index = 0; index < values.length; index++) {
console.log(index,literals[index],values[index])
}
console.log(index,literals[index])
};
msg
输出为:
0 The total is 30
1 ( 31.5
2 with tax)
2、应用
(1)防止用户恶意输入
let message =
SaferHTML`<p>${sender} has sent you a message.</p>`;
function SaferHTML(templateData) {
let s = templateData[0];
for (let i = 1; i < arguments.length; i++) {
let arg = String(arguments[i]);
// Escape special characters in the substitution.
s += arg.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
// Don't escape special characters in the template.
s += templateData[i];
}
return s;
}
上面代码中,sender变量往往是用户提供的,经过SaferHTML函数处理,里面的特殊字符都会被转义。
(2)多语言转换(国际化处理)
i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
// "欢迎访问xxx,您是第xxxx位访问者!"
i18n
为前端国际化工具。
(3)其他应用
通过标签函数,可以为模板添加条件判断和循环处理功能:
// 下面的hashTemplate函数
// 是一个自定义的模板处理函数
let libraryHtml = hashTemplate`
<ul>
#for book in ${myBooks}
<li><i>#{book.title}</i> by #{book.author}</li>
#end
</ul>
`;
除此之外,你甚至可以使用标签模板,在 JavaScript 语言之中嵌入其他语言:
jsx`
<div>
<input
ref='input'
onChange='${this.handleChange}'
defaultValue='${this.state.value}' />
${this.state.value}
</div>
`
上面的代码通过jsx
函数,将一个 DOM 字符串转为 React 对象。
模板处理函数的第一个参数(模板字符串数组),还有一个raw属性,其保存的是转义后的原字符串。