slot默认内容不渲染?先查assignedNodes()是否为空;它仅在无任何节点(含空格、换行符)分配时显示,具名插槽name须字面量全等且为直系子节点,插槽内容非响应式,更新需显式处理。

slot 默认内容不渲染?先查 assignedNodes()
插槽默认内容(<slot><p>Loading</p></slot>)只在完全没有节点被分配时才显示,不是“没传内容就兜底”,而是“连换行符、空格都算数”。
常见现象:<my-card></my-card> 能显示 fallback,但 <my-card> </my-card>(含空格)或 <my-card>\n</my-card> 就完全不显示。
验证方法必须用 JS 查:在自定义元素内部执行 this.shadowRoot.querySelector('slot').assignedNodes(),返回空数组才表示 fallback 会生效。
注意:assignedNodes() 返回的是实时快照,DOM 变更后需重新调用;若返回非空数组,哪怕只是 [Text],fallback 就不会出现。
具名插槽 name 不匹配?大小写和空格全敏感
具名插槽的 name 和父级元素的 slot 属性必须字面量严格一致——大小写、连字符、空格一个都不能错。
子组件写 <slot name="header"></slot>,父组件只能用:<h1 slot="header">Title</h1> 或 <template slot="header"><h1>Title</h1></template>。
以下全部失败:<h1 slot="Header">(大小写)、<h1 data-slot="header">(属性名错)、<div><h1 slot="header"></h1></div>(非直系子节点)。
Web Components 中不报错,只是静默丢弃;Vue 中同理,v-slot:[dynamicName] 的 dynamicName 必须是字符串,不能为 null 或 undefined,否则直接报错。
插槽内容更新不响应?它不是响应式代理
<slot> 分发的是 DOM 节点引用,不是数据绑定通道。父组件改了响应式变量,插槽内静态写法不会重渲染。
错误写法:<my-card>{{ title }}</my-card> —— title 变化时,整个插槽内容不会刷新。
正确做法分场景:
• Vue 中:用 <template v-slot:default>{{ title }}</template>,让 Vue 把插槽内容纳入响应式更新链
• Web Components 中:监听 slotchange 事件,再手动调用 this.render() 或更新影子 DOM
• 作用域插槽传递数据时,必须用 v-slot="{ user }" 解构,漏掉大括号或字段名会得到 undefined
slot 标签写在哪?必须在 Shadow DOM 里
<slot> 是原生 Web Components 机制,只在 Shadow DOM 内生效,三个前提缺一不可:
• 自定义元素已定义(customElements.define())
• 构造函数中调用了 this.attachShadow({ mode: 'open' })
• <slot> 标签被插入到该 shadowRoot 中(比如通过 shadowRoot.innerHTML = '<slot></slot>')
直接把 <slot> 写在普通 HTML 页面或 Light DOM 里,浏览器当未知标签处理,既不解析也不投射。
React 和纯 HTML 页面里没有原生 <slot> 语义,别混用;Vue 中的 <slot> 是编译器指令,只在组件模板里有效。
立即学习“前端免费学习笔记(深入)”;
插槽最麻烦的地方不是语法难记,而是它不报错、不警告、不提示——内容“消失”时,你得同时盯住四件事:自定义元素定义是否完整、attachShadow() 是否执行、Light DOM 子节点是否直系、slot 属性拼写是否零误差。



















