web components中slot需在shadow dom中生效,仅直系子节点可被投射,具名插槽严格匹配slot属性,默认插槽仅接收首个无slot属性的节点,::slotted()仅支持单层选择器,slotchange事件用于响应内容变化。

必须启用Shadow DOM才能让slot生效
slot只在自定义元素挂载了Shadow Root后才起作用。普通HTML标签(如
)无法使用slot,哪怕写了也不会报错,只是被浏览器忽略。
- 正确做法:用
customElements.define()注册自定义标签,构造函数中调用this.attachShadow({ mode: 'open' }) - 错误示例:直接在页面里写
<div><slot></slot></div>——完全无效
内容必须是直系子节点才能被投射
外部传入的内容需紧贴自定义元素标签,不能嵌套在中间容器里。
- ✅ 有效结构:
<my-card><h2 slot="title">欢迎</h2> <p>这里是正文</p> </my-card>
- ❌ 无效结构(
被
包裹,不再是直系子节点):<my-card><div> <h2 slot="title">欢迎</h2> </div> </my-card>具名插槽与默认插槽按规则匹配
- 具名插槽:
<slot name="header"></slot>只匹配带slot="header"属性的元素,字符串完全一致、区分大小写 - 默认插槽:
<slot></slot>(无name)接收所有未带slot属性的直系子节点,且只匹配第一个;后续同级<slot></slot>不会继续分发剩余内容 - 多个同名slot时,每个slot会按顺序各接收一个匹配节点(不是复制多份,而是依次分配)
利用fallback和::slotted()增强可用性
-
<slot>加载中...</slot>中的内容仅在无节点被分配时显示;只要有一个文本节点(哪怕只是换行符),fallback就不出现 - 样式化投射内容只能用
::slotted()伪类,且仅支持单层选择器:- ✅
::slotted(h2)、::slotted([slot="footer"]) - ❌
::slotted(div h2)、::slotted(h2 span)、::slotted(*)
- ✅
动态响应内容变化要靠slotchange事件
-
slotchange在Light DOM内容增删后触发,首次渲染不触发 - 在事件回调中调用
slot.assignedNodes({ flatten: true })获取当前所有投射节点(含文本节点) - 若需过滤纯文本,可用
slot.assignedElements()只返回元素节点
基本上就这些。
- 具名插槽:
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











