JS标签化模板

# 标签化模板

# 1. 标签化模板是什么

标签模板是模板字符串使用的一种高级形式,用代码示意就是 ——

这是我们常见的模板字符串:

1
2
const author = 'zhangxinxu';
console.log(`write by ${author}`);

这个就是标签模板,是模板字符串使用的高级形式:

1
2
3
4
5
const author = 'zhangxinxu';
function tag (arr, exp) {
return `${arr[0]}${exp}`;
}
console.log(tag`write by ${author}`);

两段内容返回的结果是一样的。
仔细看 tag write by ${author} 这段代码,其中 tag 就是标签模板中的 “标签”, write by ${author} 就是标签模板中的 “模板”。

因此,“标签” 实际上并不是指的标签,而是类似于标签性质的函数,“模板” 则是这个函数的参数。

# 2. 标签化模板的语法

1
2
3
4
5
6
7
8
9
10
11
12
let tag = function (strings, ...values) {
// strings是一个数组,包含了模板字符串中的每一部分
// values是一个数组,包含了模板字符串中的每一部分对应的值
// 可以在这里对模板字符串进行处理,然后返回一个字符串
return strings[0] + values[0] + strings[1] + values[1] + strings[2];
};

let name = "Alice";
let age = 20;
let result = tag`My name is ${name}, I am ${age} years old.`;

console.log(result); // My name is Alice, I am 20 years old.

# 3. 标签化模板的应用

利用标签化模板,可以实现很多有趣的功能,比如:

  • 这是一段 命令式编程
1
2
3
4
5
6
7
8
9
a.style.color = getColor();
a.style.backgroundColor = getBackgroundColor();
a.style.fontSize = getFontSize();
a.style.height = height + 'px';
a.style.width = width + 'px';
a.href = href;
a.title = title;
a.target = target;
a.textContent = textContent;
  • 我们可以通过标签化模板特性将其转换成 声明式编程
1
2
3
4
5
6
7
8
9
10
11
a.styles`
color: ${getColor()};
background-color: ${getBackgroundColor()};
font-size: ${getFontSize()};
height: ${height}px;
width: ${width}px;
`.props`
href: ${href};
title: ${title};
target: ${target};
`.content(${textContent});
1
2
3
4
5
6
7
8
9
10
11
12
HTMLElement.prototype.styles = function () {
const styles = generateString(arguments)
let curStyle = this.getAttribute("style")
if(curStyle) {
curStyle += styles;
}
else {
curStyle = styles;
}
this.style = curStyle;
return this
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
HTMLElement.prototype.props = function () {
const propString = generateString(arguments)
propString
.split("\n")
.map(it => {
const prats = it.trim().split(":");
const key = prats[0].trim();
const value = parts.slice(1).join(":").trim();
if(value.indexOf(";")===value.length - 1) {
value = value.substring(0, value.length - 1)
}
return [key, value];
})
.forEach([k, v] => {
if(!k) { return; }
this[k] = v;
});
return this;
}
1
2
3
4
5
HTMLElement.prototype.content = function () {
const content = generateString(arguments);
this.textContent = content;
return this
}