在 中实现 HOC 式包装需用 useAttrs 和 useSlots 手动控制透传:显式声明 props、inheritAttrs: false、响应式合并 attrs、条件透传插槽、v-bind="$attrs" 绑定到真实 DOM 节点。

在 <script setup></script> 中实现高阶组件(HOC)式包装,核心是**用好 useAttrs 和 useSlots,配合手动控制透传位置与优先级**。它不是写一个函数去包裹组件,而是通过模板结构 + 属性合并逻辑,让封装组件既保留自身配置能力,又把父组件传来的“剩余能力”原样交给内部基础组件。
明确 props 边界,让 $attrs 只剩“可透传部分”
高阶组件的第一步,是只声明你真正要处理的 props,其余全部交由 useAttrs() 管理:
- 用
defineProps显式列出自定义属性(如size、loading、disabled),这些不会出现在attrs中 - 未声明的属性(
class、style、id、@click、@input等)自动进入attrs对象 - 若需禁用默认继承(比如根元素是 ,但想把属性透传给内部
),必须加:
defineOptions({ inheritAttrs: false })用 computed 合并 attrs 与本地逻辑,避免覆盖冲突
直接
v-bind="$attrs"最简,但容易被父组件传入同名属性覆盖(例如父组件也传了size)。更稳妥的做法是响应式合并:
Springboot Vue Builder下载从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
- 引入
useAttrs和computed - 按优先级决定谁生效:本地逻辑值 > 父组件传值 > 默认值
- 示例:
const attrs = useAttrs()<br>const mergedProps = computed(() => ({<br> ...attrs,<br> size: attrs.size || props.size || 'medium',<br> class: ['my-input', attrs.class]<br>}))
插槽透传不能只靠
,要结合useSlots做条件判断useSlots()返回的是函数,不是 DOM,所以不能直接渲染,但能用于逻辑控制:- 检查插槽是否存在:
if (slots.default) { /* 渲染默认内容 */ } - 作用域插槽照常使用:
- 需要对插槽内容做统一包装时,可在模板中用
,实现 ref/事件透传到插槽子节点
ref 和事件透传的关键:v-bind="$attrs" 必须落在最终渲染的 DOM 节点上
这是高阶组件能否“假装透明”的关键:
- 父组件写:
提交 - 子组件模板中,
v-bind="$attrs"必须绑定在真实按钮上,而不是外层容器:<template><br> <button v-bind="$attrs"><slot></slot></button><br></template>
- 这样
ref才会指向元素,@click才能被正确监听
- 引入
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









