Tagged templates 标签函数/标签模板
更倾向称做标签函数
Q:标签函数是什么?
A:本质是函数,只要函数参数形式遵守特定约定,就可使用新语法来调用 tag`string`
Q:标签函数调用 tag`string`
跟普通函数调用 tag(`string`)
有什么区别?
A:普通函数语法调用,先对参数求值,然后将值作为参数传给函数, tag(`string`)
的第一个参数是一个普通字符串;
标签函数语法调用,不对模板字符串整体进行求值,而是转换成一定数据结构传递个函数,这个数据结构就是前面说的约定。
Q:标签函数的参数实现了什么样的约定(数据结构)?
A:首个参数为 ArrayLike (Array 多出一个 raw 属性),剩余参数是模板字符串中表达式的值,截图说明
截图代码
function tag(arg1, ...others) { console.log(arg1, ...others) } const a = 1; const b = 'str' tag`${a}|||${b}`
Q:标签函数解决什么问题,应用场景是什么?
A:当需要对一个字符串模板,和一堆复杂数据结构进行处理时,就应该使用标签函数;
- 最典型的场景:
<button onClick=${() => { console.log('click button') }}>text</button>
如何返回一个 HTMLButtonElement,并将函数绑定到 click 事件上?(答案参考下文。) - 如果没有标签函数,就需要在函数位置使用占位符,然后将字符串、数据转换成标签函数参数的形式;
所以标签函数就是帮大家节省了一些前序处理步骤,并提升可读性(无需占位符,更自然)。
html 标签函数的最简化实现:
const html = function (arr, ...keys) { let result = [arr[0]]; keys.forEach(function(key, i) { if (typeof key == 'function') { result.push(i, arr[i + 1]); } else { result.push(key, arr[i + 1]); } }); // 创建 template 元素 let template = document.createElement('template'); template.innerHTML = result.join(''); // 遍历与事件添加 template.content.querySelectorAll('*').forEach(node => { let attrs = node.attributes; for (let i = attrs.length - 1; i >= 0; i--) { let attr = attrs[i].name; let value = attrs[i].value; if (/^on[a-z]+$/i.test(attr) && !isNaN(parseFloat(value))) { node.removeAttribute(attr); node.addEventListener(attr.replace(/^on/, ''), keys[Number(value)]); } } }); return template.content; }; document.body.appendChild(html`<button onClick=${() => { console.log('click button') }}>text</button>`)
效果图:
代码来源: https://www.zhangxinxu.com/wordpress/2021/12/js-tagged-templates/
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论