当前位置: 首页 > news >正文

学习笔记:Vue 透传

1. 核心概念理解

什么是“透传 Attributes”?

        透传 attribute 是指传递给组件但未在 props emits 中声明的 HTML 属性或事件监听器(如 classstyleid@click 等),这些属性会自动“穿透”到组件内部的根元素上。

示例:

<MyButton class="large" @click="onClick" />

<MyButton> 未声明 class @click,它们将被自动应用到其模板的根元素上。

2. Attributes 继承机制

单根节点组件的自动继承

当组件只有一个根节点时,所有透传 attribute 自动绑定到该根元素。

案例演示:
<!-- 子组件 MyButton.vue -->
<template><button class="btn">Click Me</button>
</template>
<!-- 父组件使用 -->
<MyButton class="large" id="submit-btn" @click="handleClick" />

✅ 渲染结果:

<button class="btn large" id="submit-btn">Click Me</button>

🔍 说明class 被合并,id 直接继承,@click 监听器也附加到 <button> 上。

class 与 style 的合并规则

原有值透传值最终结果
"btn""large""btn large"
:class="{ active: true }"class="highlight"合并生效

📌 注意:Vue 智能合并多个来源的 class style

v-on 监听器继承

  • 父级的 @click → 子组件根元素

  • 子组件自身 v-on:click 也会触发

  • 多个监听器按顺序执行

<template><button @click="innerClick">Inner Button</button>
</template><!-- 父组件调用 -->
<MyButton @click="parentClick" />

🎯 执行顺序:innerClick parentClick

3. 深层组件继承(嵌套场景)

组件可作为“透明管道”,将 attributes 逐层向下传递。

<!-- MyButton.vue -->
<template><BaseButton />
</template><!-- BaseButton.vue -->
<template><button>Base</button>
</template>
<!-- 父组件 -->
<MyButton class="primary" @click="onClick" />

✅ 结果:class @click 都透传至 <BaseButton><button> 根元素。

📌 规则:只有未声明为 propsemits 的属性才会继续透传。

4. 禁用 Attributes 继承

使用 inheritAttrs: false

适用场景:需要把 attributes 应用到非根元素上。

<script setup>
defineOptions({ inheritAttrs: false })
</script><template><div class="btn-wrapper"><button class="btn" v-bind="$attrs">Click Me</button></div>
</template>
<!-- 调用 -->
<MyButton class="large" @click="onClick" />

✅ 渲染结果:

<div class="btn-wrapper"><button class="btn large" onclick="...">Click Me</button>
</div>

$attrs 包含除 props/emits 外的所有 attribute。

5. $attrs 对象详解

数据结构示例

// 输入:
<MyButton foo-bar="value" @click="onClick" data-test="123"
/>// $attrs 内容:
{'foo-bar': 'value',onClick: Function,'data-test': '123'
}

📌 注意事项:

  • 键名保持原始大小写(如 'foo-bar'

  • 事件监听器以函数形式暴露(onClick

  • 不是响应式对象 ❌(不能 watch)

6. 多根节点组件的行为

多根组件不支持自动 attribute 透传,必须显式绑定 $attrs,否则报错。

❌ 错误示例(运行时报错):

<template><header>Header</header><main>Content</main><footer>Footer</footer>
</template>
<CustomLayout class="layout" @click="onClick" />

⚠️ 报错:Expects exactly one root element or template.

✅ 正确做法:

<template><header>Header</header><main v-bind="$attrs">Content</main><footer>Footer</footer>
</template>

或选择性绑定特定属性:

<main :class="$attrs.class" @click="$attrs.onClick">Content</main>

7. 在 JavaScript 中访问透传 Attributes

使用 useAttrs() API(推荐)

<script setup>
import { useAttrs, onUpdated } from 'vue'const attrs = useAttrs()// 注意:$attrs 不是响应式的
onUpdated(() => {console.log('Current attrs:', attrs)
})
</script>

非 script-setup 写法

export default {setup(props, ctx) {console.log(ctx.attrs) // 透传 attributes}
}

📌 提醒:不可依赖 $attrs 响应性;需响应式请用 props

8. 图表示意:Attributes 透传流程图

9. 实际案例分析

✅ 案例一:基础透传(单根 + class 合并)

<!-- ChildButton.vue -->
<template><button class="default-btn">Submit</button>
</template>
<!-- Parent.vue -->
<ChildButton class="success" />

➡️ 输出:

<button class="default-btn success">Submit</button>

✅ 案例二:禁用继承并手动分发

<!-- WrappedInput.vue -->
<script setup>
defineOptions({ inheritAttrs: false })
</script><template><div class="input-group"><input type="text" v-bind="$attrs" /></div>
</template>
<!-- 使用 -->
<WrappedInput placeholder="Enter name" class="custom-input" @input="onInput" 
/>

➡️ 结果:

<div class="input-group"><input type="text" placeholder="Enter name" class="custom-input" @input="...">
</div>

✅ 案例三:多根组件显式绑定

<!-- Layout.vue -->
<template><header>Top</header><main v-bind="$attrs">Main Content</main><footer>Bottom</footer>
</template>
<Layout class="dark-mode" @click="toggleTheme" />

➡️ <main> 元素获得 class click 事件。

10. 总结归纳

特性行为说明
单根组件attributes 自动继承至根元素
多根组件必须手动 v-bind="$attrs",否则警告
class/style与本地值进行智能合并
v-on 事件透传并叠加执行
inheritAttrs: false关闭自动继承,实现精准控制
$attrs访问所有透传属性(非响应式)
useAttrs()Composition API 中获取 $attrs

11. 关键知识点详解

  • 透传 attribute 的继承机制
    Vue 自动将未声明的 attribute 添加到组件根元素,适用于 class、style、id 等。

  • $attrs 的作用与限制
    包含所有未被消费的 attribute,可用于手动绑定,但非响应式,不可侦听变化。

  • 多根节点的绑定要求
    多个根元素时必须显式使用 v-bind="$attrs",否则会抛出运行时警告。

http://www.dtcms.com/a/390165.html

相关文章:

  • 【记录59】携带token加载图片、图片过大自行压缩、转base64、
  • CentOS 7下FTP配置全攻略
  • 利用Debezium和PostgreSQL逻辑复制实现实时数据同步架构设计与优化实践
  • Part05 数学与其他
  • 链接脚本总结
  • 模电基础:基本放大电路及其优化
  • Curl、Wget 等命令 Uses proxy env variable https_proxy 如何解决
  • 自注意力机制Self-Attention (一)
  • (论文速读)DeNVeR(可变形神经血管表示)-X射线血管造影视频的无监督血管分割
  • css实现3D变化之两面翻转的盒子效果
  • 多项式回归原理与实战:从线性扩展到非线性建模
  • 【层面二】.NET 运行时与内存管理-01(CLR/内存管理)
  • 【51单片机】【protues仿真】基于51单片机温度检测数码管系统
  • Sketch安装图文教程:从下载到账号注册完整流程
  • Day07_STM32 单片机 - 中断
  • 花瓶测试用例10条(基于质量模型)
  • C++ 之 【智能指针的简介】
  • Vue3 + xgplayer 实现多功能视频播放器:支持播放列表、自动连播与弹幕
  • 牛客算法基础noob46 约瑟夫环
  • TCP协议的详解
  • 【LeetCode】大厂面试算法真题回忆(136)——环中最长子串
  • Hystrix:熔断器
  • SQLark 实战 | 数据筛选与排序
  • 达梦Qt接口源码Qt6编译错误处理记录
  • 知识付费创作者:如何避免陷入跟风做内容的陷阱?
  • @once_differentiable 自定义算子的用处
  • 分子动力学--蛋白配体模拟
  • python第二节 基础语法及使用规范详解
  • 运维安全07 - JumpServer(堡垒机)介绍以及使用
  • 同一个电脑内两个进程间如何通信的几种方式