Vue 3 父子&爷孙组件通信

1. 父组件给子组件传值 (Props):子用父值

基本用法

父组件 (ParentComponent.vue):

vue 复制代码
<template>
  <ChildComponent :title="childTitle" :count="childCount" />
</template>

<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

const childTitle = ref('子组件标题')
const childCount = ref(10)
</script>

子组件 (ChildComponent.vue):

vue 复制代码
<template>
  <div>
    <h2>{{ title }}</h2>
    <p>Count: {{ count }}</p>
  </div>
</template>

<script setup>
// 定义 props
const props = defineProps({
  title: {
    type: String,
    required: true
  },
  count: {
    type: Number,
    default: 0
  }
})
</script>

文档参考

2. 父组件调用子组件的方法 (Expose & Ref):父用子方法

父组件 (ParentComponent.vue):

vue 复制代码
<template>
  <ChildComponent ref="childRef" />
  <button @click="callChildMethod">调用子组件方法</button>
</template>

<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

const childRef = ref(null)

function callChildMethod() {
  if (childRef.value) {
    childRef.value.increment() //直接调用子组件中的increment的方法
  }
}
</script>

子组件 (ChildComponent.vue):

vue 复制代码
<template>
  <div>子组件计数: {{ count }}</div>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)

// 暴露给父组件的方法
function increment() {
  count.value++
}

// 如果子组件中用const XX 来定义方法,就需要 使用 defineExpose 暴露方法,父组件才能用到
defineExpose({
  increment
})
</script>

文档参考

3. 子组件改变父组件中的值 (Emit Events):子改父值

父组件 (ParentComponent.vue):

vue 复制代码
<template>
  <div>父组件计数: {{ parentCount }}</div>
  <ChildComponent @update-count="updateCount" />
</template>

<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

const parentCount = ref(0)

function updateCount(newValue) {
  parentCount.value = newValue
}
</script>

子组件 (ChildComponent.vue):

vue 复制代码
<template>
  <button @click="handleClick">更新父组件计数</button>
</template>

<script setup>
// 定义 emits
const emit = defineEmits(['updateCount'])

function handleClick() {
  // 触发事件并传递新值
  emit('updateCount', 5)
}
</script>

使用 v-model 实现双向绑定:父传子&子传父

父组件 (ParentComponent.vue):

vue 复制代码
<template>
  <ChildComponent v-model="count" />
</template>

<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

const count = ref(0)
</script>

子组件 (ChildComponent.vue):

vue 复制代码
<template>
  <button @click="updateValue">增加: {{ modelValue }}</button>
</template>

<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])

function updateValue() {
  emit('update:modelValue', props.modelValue + 1)
}
</script>

文档参考

4. 子组件调用父组件的方法 (Emit Events): 子用父方法

父组件 (ParentComponent.vue):

vue 复制代码
<template>
  <ChildComponent @call-parent="parentMethod" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue'

function parentMethod(message) {
  console.log('父组件方法被调用:', message)
}
</script>

子组件 (ChildComponent.vue):

vue 复制代码
<template>
  <button @click="callParent">调用父组件方法</button>
</template>

<script setup>
const emit = defineEmits(['callParent'])

function callParent() {
  emit('callParent', '来自子组件的消息')
}
</script>

5. 其他通信方式

依赖注入 (Provide/Inject)

适合跨多层组件通信

祖先组件 (AncestorComponent.vue):

vue 复制代码
<template>
  <ParentComponent />
</template>

<script setup>
import { provide, ref } from 'vue'
import ParentComponent from './ParentComponent.vue'

const sharedData = ref('共享数据')

provide('sharedKey', sharedData)
</script>

后代组件 (DescendantComponent.vue):

vue 复制代码
<script setup>
import { inject } from 'vue'

const sharedData = inject('sharedKey')
</script>

文档参考

总结对比表

通信方式 方向 适用场景 优点 缺点
Props 父 → 子 传递初始数据 明确的数据流,易于理解 单向数据流
Emit Events 子 → 父 子组件通知父组件 明确的事件流 需要父组件监听
Refs & Expose 父 → 子 访问子组件方法/属性 直接访问 破坏封装性
v-model 双向 表单输入等双向绑定 语法糖,简洁 仅适用于特定场景
Provide/Inject 任意 跨多层组件 避免逐层传递 数据来源不明确

最佳实践建议

  1. 优先使用 props 和 emits:保持数据流的清晰和可预测性
  2. 谨慎使用 refs:这会破坏组件的封装性
  3. 复杂场景使用状态管理:如 Pinia 适用于全局或复杂状态
  4. 考虑组件设计:如果通信过于复杂,可能需要重新思考组件结构

完整文档参考

相关推荐
冰夏之夜影5 分钟前
【科普】Edge出问题后如何恢复出厂设置
前端·edge
葱头的故事1 小时前
vant van-uploader上传file文件;回显时使用imageId拼接路径
前端·1024程序员节
Mintopia1 小时前
🇨🇳 Next.js 在国内场景下的使用分析与实践指南
前端·后端·全栈
Mintopia2 小时前
深度伪造检测技术在 WebAIGC 场景中的应用现状
前端·javascript·aigc
BUG_Jia2 小时前
如何用 HTML 生成 PC 端软件
前端·javascript·html·桌面应用·1024程序员节
木易 士心2 小时前
CSS 样式用法大全
前端·css·1024程序员节
012925202 小时前
1.1 笔记 html 基础 初认识
前端·笔记·html
2501_929382652 小时前
[Switch大气层]纯净版+特斯拉版 20.5.0大气层1.9.5心悦整合包 固件 工具 插件 前端等资源合集
前端·游戏·switch·1024程序员节·单机游戏
非凡ghost2 小时前
Tenorshare 4DDiG(数据恢复软件) 最新版
前端·javascript·后端