computed通过作用域插槽暴露计算值或控制插槽显隐/切换,增强插槽动态性与复用性;不能直接修改默认插槽静态内容,需明确计算与渲染职责分离。

computed 本身不直接“操作”插槽,但它能显著增强插槽内容的动态性与复用性——关键在于:把 computed 的响应式计算结果,作为插槽内容的输入、条件或渲染依据。
让默认插槽内容随计算状态自动变化
默认插槽接收的是父组件传入的模板片段,它本身不感知子组件内部数据。但你可以在子组件中用 computed 加工 props 或本地状态,再在插槽作用域(如作用域插槽)中暴露出去,供父组件消费。
- 子组件定义一个 computed,比如 formattedTitle,基于 props.title 或 data 中字段做格式化
- 在子组件模板中,使用 <slot :title="formattedTitle"></slot> —— 这就把它变成了作用域插槽
- 父组件用 <template #default="{ title }">{{ title.toUpperCase() }}</template> 接收并二次处理
用 computed 控制具名插槽是否渲染
具名插槽本身是静态占位,但它的“是否显示”可以由逻辑驱动。computed 可以封装这类判断逻辑,比在模板里写冗长 v-if 更清晰、可复用。
- 例如子组件有 showHeader 和 hasPermission 两个响应式源,你想只在满足条件时才渲染
<slot name="header"></slot> - 定义 computed:shouldRenderHeader() { return this.showHeader && this.hasPermission }
- 模板中写:<slot name="header" v-if="shouldRenderHeader"></slot>
- 这样既保持插槽结构不变,又把展示逻辑抽离成可测试、可复用的计算属性
结合插槽与 computed 实现内容分发策略
当组件需要根据数据特征“决定插什么”,而不是“插完再判断”,computed 就成了调度中枢。
- 比如一个卡片组件,根据 item.type 返回不同插槽名:activeSlotName() { return this.item.type === 'user' ? 'user-card' : 'product-card' }
- 子组件模板中:<slot :name="activeSlotName"></slot>(注意:这里 name 是动态绑定的)
- 父组件配合提供多个具名插槽:<template #user-card>...</template> 和 <template #product-card>...</template>
- 效果等价于“运行时插槽路由”,比用 v-if 切换整块模板更轻量、更符合插槽设计意图
避免常见误区:computed 不等于插槽内容本身
需要明确:computed 不能替代插槽声明,也不能直接修改 slot 标签内的默认内容(如 <slot>默认文本</slot> 中的“默认文本”是静态 fallback,不会响应 computed 变化)。真正起效的路径只有两条:
- 通过 作用域插槽 + computed 暴露值,让父组件拿到计算后数据再决定怎么渲染
- 通过 computed 控制插槽容器的显示/切换逻辑,间接影响插槽是否生效或渲染哪个具名插槽
不复杂但容易忽略:插槽本质是内容分发机制,computed 是响应式求值机制,二者协同的关键,在于“谁负责计算、谁负责渲染”的职责划分。

















