useSlots 和 useAttrs 是组合式 API 中用于获取插槽函数和透传属性的工具:前者返回规范化插槽函数(如 slots.default() 得 VNode 数组),后者返回未声明为 props 的属性对象,常配合 v-bind="attrs" 实现属性继承与 ref/事件透传。

在 `<script setup>` 中,`useSlots` 和 `useAttrs` 是两个轻量但关键的组合式 API 工具,用于替代旧版 setup 函数中通过 `context.slots` 和 `context.attrs` 获取插槽与非 props 属性的方式。它们不返回响应式对象,而是直接提供规范化后的插槽函数和属性对象。</script>
useSlots:拿到插槽内容的函数,不是 DOM
它返回一个插槽对象,每个键(如 default、header)对应一个函数,调用该函数才得到 VNode 数组:
- 插槽存在性判断用 !!slots.default 或 slots.header !== undefined
- 不能直接操作真实 DOM —— 返回的是虚拟节点(VNode),不是元素引用
- 若需渲染,直接在模板中写
<slot name="header"></slot>;若需逻辑处理,可调用slots.header()得到 VNode 列表 - 作用域插槽的数据仍按原方式传递,比如
<slot name="item" :item="item"></slot>,父组件用v-slot:item="{ item }"解构
useAttrs:获取未声明为 props 的透传属性
它返回一个普通对象,包含所有未被 props 消费的属性(如 class、style、id、自定义属性等):
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
- 常用于“属性继承”,例如把父组件传来的 class/style 自动加到子组件根元素上:
<div v-bind="attrs"></div> - 如果想过滤某些属性(如避免透传 ref 或 key),可用解构排除:
const { ref, key, ...rest } = attrs - 注意:若组件已声明某 prop(如
size: String),同名属性就不会出现在useAttrs()结果里
常见配合用法:让插槽内容能接收 ref 或事件绑定
想给插槽内容加 ref 或监听点击?单靠 useSlots 不行,得靠 useAttrs 透传:
立即学习“前端免费学习笔记(深入)”;
- 子组件模板中用
<slot v-bind="attrs"></slot>,把父组件传入的所有 attrs(含ref、@click等)自动挂到插槽根节点 - 父组件中写
<mycomp ref="slotRef"><button>按钮</button></mycomp>,此时slotRef就指向插槽内<button></button>渲染后的实际 DOM 元素 - 这比手动遍历 VNode 并查找 DOM 节点更可靠,也符合 Vue 的设计意图
类型提示与注意事项
搭配 TypeScript 使用时:
-
useSlots()返回类型是Record<string slot></string>,Slot 类型来自vue类型定义,支持泛型约束(如Slot) -
useAttrs()返回Data类型(即Record<string unknown></string>),建议用as const或接口做运行时校验 - 不要在模板中直接调用
slots.xxx()—— 这会破坏响应式更新,应交由<slot></slot>标签处理 - 两者都只能在组件 setup 阶段调用,不能在普通函数或副作用中使用

















