让我开始描述什么是插槽以及它们解决了什么问题。
刚刚停放的数据
在你的布局中有槽是 HTML 尝试让你在布局中放置一些数据,然后通过 JavaScript 处理它。
你甚至不需要 Shadow DOM 来使用槽,你只需要一个带有命名槽的模板来放置值。
<user-data>
<img src="..." slot="avatar">
<span slot="nick-name">...</span>
<span slot="full-name">...</span>
</user-data>
你能发现那个组件和下面的 JavaScript 之间的区别吗?
const userData = {
avatar: '...',
nickName: '...',
fullName: '...'
};
换句话说,使用下面这样的函数,我们已经可以将槽转换为由属性寻址的有用数据。
function slotsAsData(parent) {
const data = {};
parent.querySelectorAll('[slot]').forEach(el => {
// convert 'nick-name' into 'nickName' for easy JS access
// set the *DOM node* as data property value
data[el.getAttribute('slot').replace(
/-(\w)/g,
($0, $1) => $1.toUpperCase())
] = el; // <- this is a DOM node, not a string ;-)
});
return data;
}
插槽作为 hyperHTML 插值
现在我们有了解决插槽的方法,我们所需要的只是一种将它们放置在布局中的方法。
理论上,我们不需要自定义元素来实现它。
document.querySelectorAll('user-data').forEach(el => {
// retrieve slots as data
const data = slotsAsData(el);
// place data within a more complex template
hyperHTML.bind(el)`
<div class="user">
<div class="avatar">
${data.avatar}
</div>
${data.nickName}
${data.fullName}
</div>`;
});
但是,如果我们想使用 Shadow DOM 来保护样式和节点免受不希望的页面/第三部分污染,我们可以按照基于自定义元素的代码笔示例中所示的方式进行操作。
正如你所看到的,唯一需要的 API 是 attachShadow ,并且有一个超轻量级的 polyfill,它的最小压缩重量为 1.6K。
最后但并非最不重要的一点是,您可以在 hyperHTML 模板文字中使用插槽并让浏览器进行转换,但这需要更重的 polyfill,我不建议在生产中使用它,特别是当有更好和更轻的替代方案时,如这里所示。
我希望这个答案对你有所帮助。