slot是浏览器原生web components机制,仅在shadow dom中生效,必须调用attachshadow()、内容为直系子节点、name严格字符串匹配,否则静默丢弃。

slot 不是 Vue 或 React 的语法糖,它是浏览器原生支持的 Web Components 内容分发机制,只在 Shadow DOM 中生效。没挂 Shadow Root,slot 就完全不工作——内容既不会渲染,也不会报错,只是静默丢弃。
为什么写了 slot 却没显示任何内容?
这是最常卡住人的第一步。现象是:父组件写了 <my-card><h2 slot="title">Hello</h2></my-card>,子组件里也写了 <slot name="title"></slot>,但页面空白。
- 检查是否调用了
this.attachShadow({ mode: 'open' })—— 没这句,slot根本不参与分发逻辑 - 确认外部元素是自定义元素的**直系子节点**:
<my-card><div><h2 slot="title">Hello</h2></div></my-card>中的<h2></h2>不会被捕获,因为被<div> 隔了一层 <li> <code>slot元素必须写在 Shadow DOM 内部(比如shadowRoot.innerHTML或shadowRoot.appendChild(template.content.cloneNode(true))),不能直接写在 Light DOM 里 - 如果用了
{ mode: 'closed' },JS 无法访问shadowRoot,调试时会误判为“没生效” -
<slot name="header"></slot>只匹配<h1 slot="header">...</h1> -
<h1 slot="Header"></h1>、<h1 slot="header-text"></h1>、<h1 slot=" header "></h1>全都不匹配,内容直接丢弃 - 没写
name的<slot></slot>隐式名为"default",接收所有没带slot属性的直系子节点 - 多个默认
<slot></slot>会共享同一组节点,不是“按顺序分配”——它们都拿到全部未命名节点 - 在自定义元素内部,执行
this.shadowRoot.querySelector('slot').assignedNodes()—— 返回当前被投射进来的节点列表(含文本节点) - 返回空数组?说明没内容进来,大概率是父子层级不对、
slot属性拼错、或 Shadow Root 没正确挂载 - 想监听动态变化?用
slotchange事件:shadowRoot.querySelector('slot').addEventListener('slotchange', () => { ... }) - 注意:
assignedNodes({ flatten: true })可展开具名 slot 的 fallback 内容,但默认不展开
slot 的 name 匹配规则有多严格?
匹配不是模糊查找,而是精确字符串比对,且区分大小写、不支持空格和特殊字符。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
怎么验证插槽有没有被正确填充?
别只靠肉眼观察渲染结果。Shadow DOM 的投射是声明式的,但实际分配状态得靠 API 查。
真正容易被忽略的是:slot 本身不渲染,也不出现在最终 DOM 中;它只起“路由”作用。一旦漏掉 attachShadow 或写错层级关系,问题不会报错,只会无声失效——这种静默失败,比报错更难定位。










