Vue3 透传和父子传递

在 Vue3 中,透传是一种在父子组件中,仅通过组件属性传递参数的方式,不需要单独使用 propsemit 对传递的参数进行显式声明。

透传规则

默认情况下,透传会将参数传递到子组件中,仅对于对 classstyle 的值进行合并。如果子组件中仅嵌套了另一个子组件,那么透传会继续向下传递。

html 复制代码
<!-- Child.vue -->
<template>
  <sub-child></sub-child>
</template>

但是,如果子组件是一个多层的布局,那就需要手动为每个参数指定透传的目标。否则,vue 将会发出像下面这样的警告。

Child.vue?t=1753428210893:53 Vue warn: Extraneous non-props attributes (text) were passed to component but could not be automatically inherited because component renders fragment or text or teleport root nodes.

这时,我们就需要使用 $attrs 手动为其指定传递的布局。

html 复制代码
<!-- Child.vue -->
<template>
  <div>{{ $attrs.text }}</div>
  <button></button>
</template>

如果不希望某个子组件自动继承透传,那么可以在子组件中设置 inheritAttrs: false 取消透传自动继承。

javascript 复制代码
<script setup>
defineOptions({
  inheritAttrs: false
})
</script>

透传与组件父子通信

透传除了能够传递参数,还能够为子组件传递函数。通过使用 v-bind 将父组件的任意函数透传到子组件中,配合 callback 函数的入参,我们就能将子组件的参数回传给父组件,并通过父组件的函数进行数据更新。

html 复制代码
<!-- Parent.vue -->
<template>
  <div>
    <p>父组件变量值:{{ count }}</p>
    <br />
    <child :callback="changeCount" :text="text"></child>
  </div>
</template>

<script setup>
  import { ref } from "vue";
  import Child from "./Child.vue";

  const count = ref(0);
  const text = ref("这是被透传的值");

  function changeCount(newCount) {
    count.value = newCount;
  }
</script>
html 复制代码
<!-- Child.vue -->
<template>
  <div>{{ $attrs.text }}</div>
  <button @click="$attrs.callback(num)">修改父组件变量</button>
</template>

<script setup>
  const num = ref(10);
</script>

预览效果如下

此外,我们还可以在 <script setup> 中使用 useAttrs() API 来访问一个组件的所有透传。例如直接调用

html 复制代码
<!-- Child.vue -->
<script setup>
  import { ref } from "vue";
  import { useAttrs } from "vue";

  const num = ref(10);
  const attrs = useAttrs();
  attrs.callback(num.value);
</script>

结语

相比与 Props,这种传递更加符合直觉,但是也因为不需要声明的特点,在复杂布局中难以将参数建立关联,必须回到父组件中理解传递的参数。所以,只建议在清晰的布局结构中使用这种技术,防止带来技术上的心智负担。

相关推荐
程序员鱼皮1 小时前
DeepSeek Harness 最新邪修曝光!被吹成核弹的极简模式,真的夯吗?
前端·后端·ai编程
袅沫1 小时前
Nginx中部署多个前端项目——区分路径
服务器·前端
Asize1 小时前
为什么写代码前要先规划组件树?Next.js + Redis 笔记系统实战
前端·javascript·next.js
用户921080262861 小时前
6. 数据大屏 WebSocket 稳定性优化:心跳检测、断点续传和消息去重
前端
柚yuzumi1 小时前
CSS 定位布局:让元素各就各位
前端·css
光影少年1 小时前
react navite图片加载优化、大图卡顿、缓存策略
前端·react native·react.js
小林ixn1 小时前
用 Next.js 和 Redis 撸一个 Markdown 笔记系统:RSC 实战与组件化拆解
前端·redis·next.js
渣波1 小时前
重构旅行体验:基于 React 的 AI 旅游助手对话系统实战解析
前端·javascript
今日无bug1 小时前
列表转树:一道题搞懂 HashMap 在算法里的价值
前端·数据结构
用户921080262861 小时前
5. 数据大屏实时通信第一步:为什么选择 WebSocket,以及如何接入 Socket.IO
前端