Vue插槽默认内容仅在slot无任何分配节点(含空格、换行符)时渲染,具名插槽name须字面量严格匹配,动态插槽需用v-slot:[name],插槽内容非响应式,更新需显式纳入响应链。

slot 的默认内容只在「完全没有节点被分配」时才显示,不是“没传内容就兜底”,而是“连空文本节点都算数”——这点最容易误判。
为什么slot里写了默认内容却从不渲染?
浏览器对 slot 的 fallback 逻辑非常严格:
- 只要父元素有任意直系子节点(哪怕只是换行符、空格或
<span></span>),slot就认为“已分配”,默认内容立即被忽略 -
<slot><p>Loading</p></slot>在<my-comp></my-comp>中能显示;但写成<my-comp> </my-comp>(含空格)就完全不显示 - 检查是否命中 fallback,不能只看页面,得用
this.shadowRoot.querySelector('slot').assignedNodes()看返回数组是否为空
具名插槽的 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>(非直系子节点)
动态插槽名要配合 template + v-slot:[dynamicName] 使用
Vue 场景下,纯 HTML 的 <slot name="xxx"> 不支持绑定,必须走 Vue 指令系统:
立即学习“前端免费学习笔记(深入)”;
- 子组件中仍用静态
name:<slot :name="dynamicSlotName"></slot>❌ 不生效;应保持<slot name="header"></slot>等固定名 - 父组件动态绑定插槽位置:
<template v-slot:[slotName]>...</template>,其中slotName是响应式变量 - 注意:
v-slot:[slotName]只接受字符串,不能是对象或函数;若值为null或undefined,会报错而非静默降级
插槽内容不是响应式代理,更新需主动触发
slot 分发的是 DOM 节点引用,不是数据通道。父组件改了数据,插槽内部不会自动重渲染:
- 错误写法:
<my-card>{{ title }}</my-card>——title变化时,整个插槽内容不会刷新 - 正确做法:用
<template v-slot:default>{{ title }}</template>,让 Vue 把插槽内容纳入响应式更新链 - Web Components 中无自动响应,需监听
slotchange事件,并手动调用this.render()或更新影子 DOM
真正难调试的从来不是怎么写,而是「为什么写了却没效果」——绝大多数问题出在节点层级、空格/换行、name 字符串匹配或响应式上下文缺失上,而不是语法本身。



















