news 2026/8/12 17:19:12

八、Vue组件通信详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
八、Vue组件通信详解

一、vue2组件通信汇总表

通信方式适用场景/范围通信方向核心原理与特点
Props / $ emit父子组件父传子 / 子传父最核心的单向数据流。父传子用props,子传父通过this.$emit触发自定义事件。
v-model父子组件双向绑定语法糖。本质是props接收value,子组件通过$emit('input', val)回传数据。
.sync 修饰符父子组件双向绑定语法糖。用于子组件修改父组件的某个状态,本质是props接收属性,子组件触发update:属性名事件。
$ refs父子组件父访问子父组件通过ref属性获取子组件实例,可直接调用子组件的方法或读取数据(强耦合,慎用)。
Event Bus任意组件双向全局事件总线。创建一个空的 Vue 实例作为中转站,通过$emit发送,$on接收。
共同父组件中转兄弟组件子→父→子将共享状态提升到父组件,通过父组件的props$emit分别和两个子组件通信。
Provide / Inject祖孙组件祖先→后代依赖注入。祖先组件通过provide提供数据,后代组件通过inject注入(Vue2中默认非响应式)。
$ attrs / $ listeners跨层级组件祖先→后代跨代透传。$attrs传递未声明的属性,$listeners传递事件监听器,常用于高阶组件封装。
$ parent / $ children父子组件双向访问直接访问父/子组件实例。极易导致代码脆弱和强耦合,官方强烈建议谨慎使用。
Vuex全局任意组件集中式状态管理官方状态管理库。将公共数据抽离为全局变量,通过commitdispatch进行读写,适合中大型项目。
Slot (插槽)父子组件父→子(内容分发)父组件向子组件传递模板内容。作用域插槽可实现子组件向父组件回传数据。
路由传参页面间通信单向通过 Vue Router 的queryparamsstate在页面跳转时传递参数。

二、vue3组件通信汇总表

通信方式适用场景/范围通信方向核心原理与特点
Props / Emits父子组件父传子 / 子传父核心通信。Vue3 推荐使用defineProps接收数据,defineEmits声明并触发事件。
v-model / defineModel父子组件双向绑定语法糖升级。Vue3.4+ 推荐使用defineModel宏,无需再手动定义 props 和 emits,实现极简双向绑定。
Ref + DefineExpose父子组件父访问子替代了部分$refs场景。子组件必须通过defineExpose显式暴露属性和方法,父组件才能通过ref访问。
$ attrs跨层级组件祖先→后代属性与事件合并透传。Vue3 将$listeners合并到了$attrs中,只需v-bind="$attrs"即可透传所有未声明属性和事件。
Provide / Inject祖孙组件祖先→后代依赖注入升级。在<script setup>中使用provideinject函数,且原生支持响应式(直接传 ref/reactive 即可)。
Mitt 事件总线任意组件双向替代了 Vue2 的 Event Bus。由于 Vue3 移除了$on/$off,官方推荐使用轻量级第三方库mitt实现全局事件通信。
Pinia全局任意组件集中式状态管理Vue3 官方首推状态管理库(替代 Vuex)。去除了繁琐的mutations,完美支持 TypeScript,API 更简洁。
Teleport特殊场景DOM 渲染位置Vue3 新增。允许将组件的模板渲染到 DOM 中的其他位置(如<body>),常用于弹窗、下拉菜单等。
共同父组件中转兄弟组件子→父→子与 Vue2 原理一致。将共享状态提升到父组件,通过propsemits分别和两个子组件通信。
路由传参页面间通信单向与 Vue2 原理一致。通过 Vue Router 的queryparamsstate传递参数。
浏览器缓存跨页面持久化单向利用localStoragesessionStoragewindow对象在组件间共享或持久化数据。

三、vue2组件通信详解

Vue2 提供了多种组件通信方式,适用于不同的场景和需求。合理选择通信方式可以让组件间的数据流动更加清晰、可维护。

1. Props / $emit(最核心、最推荐)

传值范围:Props(父传子),$emit(子传父)

适用场景:父子组件之间的直接通信,是最基础、最常用的通信方式。

子组件 (Child.vue)

<template> <div> <!-- 2. 渲染父组件传过来的数据 --> <p>接收到的消息:{{ msg }}</p> <!-- 4. 点击按钮,触发事件并把数据传回给父组件 --> <button @click="$emit('change', '我是子组件传回的数据')">通知父组件</button> </div> </template> <script> export default { // 1. 声明接收父组件的数据 props: ['msg'] } </script>

父组件 (Parent.vue)

<template> <div> <!-- 3. 把数据传给子组件,并监听子组件的事件 --> <Child :msg="parentMsg" @change="handleChildEvent" /> </div> </template> <script> export default { data() { return { parentMsg: '我是父组件的数据' } }, methods: { // 5. 接收子组件传过来的数据 handleChildEvent(data) { console.log(data); // 输出: '我是子组件传回的数据' } } } </script>

核心要点

  • 父组件通过v-bind(或:)将数据传递给子组件
  • 子组件通过props声明接收的数据
  • 子组件通过$emit触发自定义事件,将数据传回父组件
  • 数据流是单向的:父 → 子(props),子 → 父(事件)

2. v-model(双向绑定语法糖)

传值范围:父子双向通信(父传子 value,子传父 input 事件)

适用场景:表单元素或需要双向绑定的自定义组件。

子组件 (Child.vue)

<template> <div> <!-- 2. 绑定接收到的 value 属性,并在输入时触发 input 事件 --> <input :value="value" @input="$emit('input', $event.target.value)" /> </div> </template> <script> export default { // 1. 默认接收 value 属性 props: ['value'] } </script>

父组件 (Parent.vue)

<template> <div> <p>父组件的值:{{ text }}</p> <!-- 3. 使用 v-model,实现父子数据双向同步 --> <Child v-model="text" /> </div> </template> <script> export default { data() { return { text: '' } } } </script>

v-model 原理

写法等价写法说明
<Child v-model="text" /><Child :value="text" @input="text = $event" />默认绑定 value 属性和 input 事件
v-model.trim="text":value="text" @input="text = $event.trim()"带修饰符的 v-model

自定义 v-model:在子组件中通过model选项可以修改默认的 prop 和事件名。

exportdefault{model:{prop:'checked',// 修改默认的 value 属性名event:'change'// 修改默认的 input 事件名},props:['checked']}

3. .sync 修饰符(Vue2 特有)

传值范围:父子双向通信(父传子 属性,子传父 update:属性 事件)

适用场景:需要双向绑定的多个 props,Vue3 中已移除,改用多个 v-model 实现。

子组件 (Child.vue)

<template> <div v-if="visible"> <p>这是一个弹窗</p> <!-- 2. 触发 update:visible 事件,修改父组件的值 --> <button @click="$emit('update:visible', false)">关闭弹窗</button> </div> </template> <script> export default { // 1. 接收父组件传过来的状态 props: ['visible'] } </script>

父组件 (Parent.vue)

<template> <div> <button @click="isShow = true">打开弹窗</button> <!-- 3. 使用 .sync,子组件修改时会自动同步到 isShow --> <Child :visible.sync="isShow" /> </div> </template> <script> export default { data() { return { isShow: false } } } </script>

.sync 修饰符原理

语法糖写法等价写法说明
:visible.sync="isShow":visible="isShow" @update:visible="isShow = $event"单个属性双向同步
支持多个属性:width.sync="w" :height.sync="h"多个属性分别同步

4. $refs(父组件直接访问子组件)

传值范围:父组件单向访问子组件(直接获取子组件实例)

适用场景:父组件需要直接调用子组件的方法或访问其数据,如表单校验。

子组件 (Child.vue)

<template> <input v-model="inputValue" placeholder="请输入内容" /> </template> <script> export default { data() { return { inputValue: '' } }, methods: { // 2. 暴露给父组件调用的方法 validate() { if (!this.inputValue) { alert('内容不能为空!'); return false; } return true; } } } </script>

父组件 (Parent.vue)

<template> <div> <!-- 1. 给子组件打上 ref 标记 --> <Child ref="myForm" /> <button @click="handleSubmit">提交</button> </div> </template> <script> export default { methods: { handleSubmit() { // 3. 通过 $refs 直接调用子组件内部的方法 const isValid = this.$refs.myForm.validate(); if (isValid) { console.log('验证通过!'); } } } } </script>

使用注意事项

  • $refs只在组件渲染完成后才填充,应在mounted及之后的生命周期中访问
  • 过度使用$refs会破坏组件封装性,应优先使用 props 和事件
  • 不要在使用v-for的循环中依赖$refs的顺序

5. Event Bus(全局事件总线)

传值范围:任意组件间通信(常用于兄弟组件、无直接关系的组件)

适用场景:非父子组件、跨层级组件间的通信,适合小型项目。

创建 Event Bus

// event-bus.jsimportVuefrom'vue';exportconstEventBus=newVue();

发送方组件 (ComponentA.vue)

<template> <div> <!-- 1. 点击按钮,通过全局总线发送数据 --> <button @click="$bus.$emit('share-data', '我是A组件的数据')">发送数据给B</button> </div> </template> <script> import { EventBus } from './event-bus.js'; export default { created() { this.$bus = EventBus; } } </script>

接收方组件 (ComponentB.vue)

<template> <div> <p>接收到的消息:{{ receivedMsg }}</p> </div> </template> <script> import { EventBus } from './event-bus.js'; export default { data() { return { receivedMsg: '' } }, mounted() { // 2. 在挂载时,监听全局总线的事件 this.$bus = EventBus; this.$bus.$on('share-data', (data) => { this.receivedMsg = data; console.log('B组件收到了:', data); }); }, beforeDestroy() { // 3. 组件销毁前,务必解绑事件,防止内存泄漏 this.$bus.$off('share-data'); } } </script>

Event Bus 优缺点

  • 优点:实现任意组件间通信,简单灵活
  • 缺点:事件名容易冲突,难以追踪事件流向,容易造成内存泄漏(忘记解绑),不适合大型项目

6. 共同父组件中转

传值范围:兄弟组件之间(子传父,父再传子)

适用场景:两个兄弟组件需要通信,通过共同的父组件作为中转站,数据流清晰可控。

发送方兄弟组件 (BrotherA.vue)

<template> <div> <!-- 1. 触发事件,把数据传给父组件 --> <button @click="$emit('send-to-b', '来自兄弟A的消息')">通知兄弟B</button> </div> </template>

共同父组件 (Parent.vue)

<template> <div> <!-- 2. 监听A的事件,把数据存起来,再通过props传给B --> <BrotherA @send-to-b="handleSend" /> <BrotherB :msg="msgForB" /> </div> </template> <script> export default { data() { return { msgForB: '' } }, methods: { handleSend(data) { this.msgForB = data; } } } </script>

接收方兄弟组件 (BrotherB.vue)

<template> <div> <!-- 3. 渲染父组件传过来的数据 --> <p>收到A的消息:{{ msg }}</p> </div> </template> <script> export default { props: ['msg'] } </script>

核心要点

  • 兄弟组件本身不能直接通信,必须通过父组件
  • 数据流:BrotherA → $emit → Parent → props → BrotherB
  • 适合组件层级较浅、逻辑简单的场景

7. Provide / Inject(依赖注入)

传值范围:祖先组件传给任意深度的后代组件(跨层级单向传递)

适用场景:深层嵌套组件需要获取祖先组件的数据,避免通过每一层 props 逐层传递(prop 逐级透传)。

祖先组件 (Grandpa.vue)

<script> export default { data() { return { theme: 'dark' } }, // 1. 提供数据,所有后代都能拿到 provide() { return { theme: this.theme } } } </script>

任意后代组件 (DeepChild.vue)

<template> <div> <!-- 2. 直接使用注入的数据,不需要中间层传递 --> <p>当前主题:{{ theme }}</p> </div> </template> <script> export default { // 声明需要注入的数据 inject: ['theme'] } </script>

注意事项

  • provide的数据不是响应式的(除非传入响应式对象),因此适合注入常量或一次性配置
  • 若需要响应式数据,可以传一个Vue.observable对象或使用computed属性
  • 滥用provide/inject会造成数据来源不清晰,应谨慎使用

8. $attrs / $listeners(跨代透传)

传值范围:祖先组件传给深层后代(中间组件只做透传,不消费数据)

适用场景:封装高阶组件时,将父组件传入的未声明 props 和事件自动传递给下层组件,避免手动一一传递。

祖先组件 (App.vue)

<template> <div> <!-- 1. 传递属性和事件给中间组件 --> <MiddleComp :title="title" @click-btn="handleClick" /> </div> </template> <script> export default { data() { return { title: 'hello' } }, methods: { handleClick() { console.log('按钮被点击'); } } } </script>

中间组件 (MiddleComp.vue)

<template> <div> <!-- 2. 自己不消费,直接把所有未声明的属性和事件透传给孙子组件 --> <GrandChild v-bind="$attrs" v-on="$listeners" /> </div> </template> <script> export default { // 3. 关闭默认绑定到根元素的行为,让透传更干净 inheritAttrs: false } </script>

孙子组件 (GrandChild.vue)

<template> <div> <!-- 4. 正常接收祖先组件传过来的 props 和事件 --> <p>标题:{{ title }}</p> <button @click="$emit('click-btn')">触发祖先事件</button> </div> </template> <script> export default { props: ['title'] } </script>

核心要点

  • $attrs包含父作用域中不作为 prop 被识别的 attribute 绑定(class 和 style 除外)
  • $listeners包含父作用域中的 v-on 事件监听器(不含.native修饰符)
  • inheritAttrs: false可以阻止默认的根元素继承,让透传更干净
  • 在 Vue3 中,$listeners被合并到$attrs中,事件也以onXxx形式存在

9. $parent / $children

传值范围:父子组件之间(直接访问实例,破坏封装性,极不推荐)

适用场景:应急情况下快速访问父子组件实例,但绝不应作为常规通信方式。

父组件 (Parent.vue)

<template> <div> <Child /> <!-- 1. 父组件通过 $children 访问子组件(注意:是个数组且无序) --> <button @click="$children[0].childMethod()">调用子组件方法</button> </div> </template>

子组件 (Child.vue)

<script> export default { data() { return { childMsg: '我是子组件的数据' } }, methods: { childMethod() { console.log('子组件方法被调用了'); } }, mounted() { // 2. 子组件通过 $parent 直接读取/修改父组件的数据 console.log(this.$parent.childMsg); } } </script>

为什么不推荐

  • 强耦合:子组件与父组件紧绑定,难以复用
  • 顺序不可靠:$children的顺序不保证与模板顺序一致
  • 难以维护:直接修改父子组件的数据会让数据流混乱,调试困难
  • 替代方案:优先使用 props、事件、Vuex 等单向数据流方案

四、vue3组件通信

Vue3 在组件通信方面进行了全面升级,引入了 Composition API 和多个编译器宏,让通信方式更加简洁和灵活。

1. Props / Emits(最核心、最推荐)

传值范围:Props(父传子),Emits(子传父)

适用场景:父子组件之间的直接通信,使用<script setup>语法后声明更简洁,是 Vue3 中最推荐的通信方式。

子组件 (Child.vue)

<template> <div> <!-- 2. 渲染父组件传过来的数据 --> <p>接收到的消息:{{ msg }}</p> <!-- 4. 点击按钮,触发事件并把数据传回给父组件 --> <button @click="emit('change', '我是子组件传回的数据')">通知父组件</button> </div> </template> <script setup> // 1. 声明接收父组件的数据 defineProps(['msg']) // 3. 声明要触发的事件 const emit = defineEmits(['change']) </script>

父组件 (Parent.vue)

<template> <div> <!-- 5. 把数据传给子组件,并监听子组件的事件 --> <Child :msg="parentMsg" @change="handleChildEvent" /> </div> </template> <script setup> import { ref } from 'vue' const parentMsg = ref('我是父组件的数据') // 6. 接收子组件传过来的数据 const handleChildEvent = (data) => { console.log(data) // 输出: '我是子组件传回的数据' } </script>

核心要点

  • definePropsdefineEmits是编译器宏,无需导入即可使用
  • 子组件通过defineEmits声明事件,返回的emit函数用于触发事件
  • 父组件使用@事件名监听,和 Vue2 的$emit用法一致
  • 数据流依然是单向的:父 → 子(props),子 → 父(emits)

2. v-model / defineModel(双向绑定)

传值范围:父子双向通信(父传子 modelValue,子传父 update:modelValue 事件)

适用场景:表单元素或需要双向绑定的自定义组件,Vue3.4+ 推荐使用defineModel宏,代码更简洁。

子组件 (Child.vue)

<template> <div> <!-- 2. 直接绑定 defineModel 返回的变量,修改它会自动同步给父组件 --> <input v-model="model" placeholder="请输入内容" /> </div> </template> <script setup> // 1. 使用 Vue3.4+ 推荐的 defineModel 宏 const model = defineModel() </script>

父组件 (Parent.vue)

<template> <div> <p>父组件的值:{{ text }}</p> <!-- 3. 使用 v-model,实现父子数据双向同步 --> <Child v-model="text" /> </div> </template> <script setup> import { ref } from 'vue' const text = ref('') </script>

v-model 进阶用法

写法说明
<Child v-model="text" />默认绑定modelValue属性和update:modelValue事件
<Child v-model:title="title" />自定义参数,绑定title属性和update:title事件
多个 v-model<Child v-model:name="name" v-model:age="age" />,子组件中用defineModel('name')defineModel('age')分别声明

低版本兼容写法(Vue3.4 之前):

<script setup> const props = defineProps(['modelValue']) const emit = defineEmits(['update:modelValue']) const model = computed({ get: () => props.modelValue, set: (value) => emit('update:modelValue', value) }) </script>

3. Ref + DefineExpose(父组件直接访问子组件)

传值范围:父组件单向访问子组件(直接获取子组件暴露的实例)

适用场景:父组件需要直接调用子组件的方法或访问其数据,如表单校验、触发动画、获取子组件状态等。

子组件 (Child.vue)

<template> <input v-model="inputValue" placeholder="请输入内容" /> </template> <script setup> import { ref } from 'vue' const inputValue = ref('') // 2. 显式暴露给父组件调用的方法 const validate = () => { if (!inputValue.value) { alert('内容不能为空!') return false } return true } // 3. 必须通过 defineExpose 暴露,父组件才能访问 defineExpose({ validate }) </script>

父组件 (Parent.vue)

<template> <div> <!-- 1. 给子组件打上 ref 标记 --> <Child ref="myFormRef" /> <button @click="handleSubmit">提交</button> </div> </template> <script setup> import { ref } from 'vue' const myFormRef = ref(null) const handleSubmit = () => { // 4. 通过 ref.value 直接调用子组件暴露的方法 const isValid = myFormRef.value.validate() if (isValid) console.log('验证通过!') } </script>

使用注意事项

  • <script setup>中,组件默认是“封闭”的,必须通过defineExpose显式暴露属性或方法
  • 父组件的ref变量名需与模板中的ref属性值一致
  • 访问子组件实例需在onMounted或之后的生命周期中,确保组件已挂载
  • 过度使用ref访问子组件会破坏封装性,应优先使用 props 和 emits

4. $attrs(属性透传)

传值范围:祖先组件传给深层后代(中间组件只做透传,不消费数据)

适用场景:封装高阶组件或基础 UI 组件时,将父组件传入的未声明 props 和事件自动传递给下层组件,避免手动一一传递。

祖先组件 (App.vue)

<template> <div> <!-- 1. 传递属性和事件给中间组件 --> <MiddleComp :title="title" @click-btn="handleClick" /> </div> </template> <script setup> import { ref } from 'vue' const title = ref('hello') const handleClick = () => { console.log('按钮被点击') } </script>

中间组件 (MiddleComp.vue)

<template> <div> <!-- 2. 自己不消费,直接把所有未声明的属性和事件透传给孙子组件 --> <GrandChild v-bind="$attrs" /> </div> </template> <script setup> // 3. 关闭默认绑定到根元素的行为,让透传更干净 defineOptions({ inheritAttrs: false }) </script>

孙子组件 (GrandChild.vue)

<template> <div> <!-- 4. 正常接收祖先组件传过来的 props 和事件 --> <p>标题:{{ title }}</p> <button @click="$emit('click-btn')">触发祖先事件</button> </div> </template> <script setup> defineProps(['title']) </script>

核心要点

  • 在 Vue3 中,$listeners已被合并到$attrs中,事件监听器以onXxx的形式存在
  • 中间的透传组件通过v-bind="$attrs"即可将所有未声明的属性和事件一次传递给下层组件
  • 使用defineOptions({ inheritAttrs: false })可以阻止默认的根元素继承,避免属性污染
  • 孙子组件中通过defineProps声明需要的属性,通过$emit触发事件即可

5. Provide / Inject(依赖注入)

传值范围:祖先组件传给任意深度的后代组件(跨层级单向传递)

适用场景:深层嵌套组件需要获取祖先组件的数据,避免通过每一层 props 逐层传递,适合全局配置(如主题、语言、权限等)和跨层级共享状态。

祖先组件 (Grandpa.vue)

<template> <div> <DeepChild /> </div> </template> <script setup> import { provide, ref } from 'vue' const theme = ref('dark') // 1. 提供数据,所有后代都能拿到 provide('theme', theme) </script>

任意后代组件 (DeepChild.vue)

<template> <div> <!-- 2. 直接使用注入的数据,不需要中间层传递 --> <p>当前主题:{{ theme }}</p> </div> </template> <script setup> import { inject } from 'vue' // 声明需要注入的数据 const theme = inject('theme') </script>

核心要点

  • 在 Vue3 的<script setup>中,使用provideinject函数,需要从vue中导入
  • provide的第一个参数是注入的 key(字符串或 Symbol),第二个参数是值
  • inject的第一个参数是 key,第二个参数是可选默认值
  • 与 Vue2 不同,Vue3 的provide数据默认是响应式的(如果传入的是 ref 或 reactive 对象),后代组件可以直接响应变化
  • 适合替代 Vuex/Pinia 的部分功能,用于跨层级共享一些简单的状态

注意事项

  • 要修改注入的数据,推荐在祖先组件中提供修改方法,而不是在后代组件中直接修改(保持单向数据流)
  • 使用 Symbol 作为 key 可以避免命名冲突
  • 对于复杂的全局状态管理,仍推荐使用 Pinia

6. Mitt 事件总线

传值范围:任意组件间通信(常用于兄弟组件、无直接关系的组件)

适用场景:Vue3 中移除了$on$off$once等实例方法,无法使用 Vue2 的 Event Bus。推荐使用第三方库mitt实现轻量级全局事件总线,适合小型项目或需要跨组件通信的场景。

安装 mitt

npminstallmitt

创建 mitt 实例

// utils/eventBus.jsimportmittfrom'mitt'constemitter=mitt()exportdefaultemitter

发送方组件 (ComponentA.vue)

<template> <div> <!-- 1. 点击按钮,通过全局总线发送数据 --> <button @click="emitter.emit('share-data', '我是A组件的数据')">发送数据给B</button> </div> </template> <script setup> import emitter from '@/utils/eventBus' // 引入配置好的 mitt 实例 </script>

接收方组件 (ComponentB.vue)

<template> <div> <p>接收到的消息:{{ receivedMsg }}</p> </div> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue' import emitter from '@/utils/eventBus' const receivedMsg = ref('') const handleData = (data) => { receivedMsg.value = data console.log('B组件收到了:', data) } // 2. 在挂载时,监听全局总线的事件 onMounted(() => emitter.on('share-data', handleData)) // 3. 组件卸载时,务必解绑事件,防止内存泄漏 onUnmounted(() => emitter.off('share-data', handleData)) </script>

mitt 核心 API

方法说明
emitter.emit(event, data)触发事件,传递数据
emitter.on(event, callback)监听事件,当事件触发时执行回调
emitter.off(event, callback)解绑指定事件和回调
emitter.all.clear()清除所有事件监听器

使用注意事项

  • 事件名建议使用常量或字符串枚举,避免硬编码分散
  • 必须成对使用onoff,在onUnmounted中解绑,防止内存泄漏
  • mitt 适合小型应用,大型项目推荐使用 Pinia 或 Vuex 作为状态管理

7. 共同父组件中转

传值范围:兄弟组件之间(子传父,父再传子)

适用场景:两个兄弟组件需要通信,通过共同的父组件作为中转站,数据流清晰可控,适合组件层级较浅、逻辑简单的场景。

发送方兄弟组件 (BrotherA.vue)

<template> <div> <!-- 1. 触发事件,把数据传给父组件 --> <button @click="$emit('send-to-b', '来自兄弟A的消息')">通知兄弟B</button> </div> </template>

共同父组件 (Parent.vue)

<template> <div> <!-- 2. 监听A的事件,把数据存起来,再通过props传给B --> <BrotherA @send-to-b="handleSend" /> <BrotherB :msg="msgForB" /> </div> </template> <script setup> import { ref } from 'vue' const msgForB = ref('') const handleSend = (data) => { msgForB.value = data } </script>

接收方兄弟组件 (BrotherB.vue)

<template> <div> <!-- 3. 渲染父组件传过来的数据 --> <p>收到A的消息:{{ msg }}</p> </div> </template> <script setup> defineProps(['msg']) </script>

核心要点

  • 兄弟组件本身不能直接通信,必须通过父组件作为中介
  • 数据流:BrotherA → emits → Parent → props → BrotherB
  • 使用<script setup>语法后,通过$emit触发事件,通过defineProps接收数据
  • 适合简单的兄弟组件通信,如果多个兄弟组件或复杂状态,建议使用状态管理(Pinia)或事件总线
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/12 17:18:26

Windows注册表清理指南:彻底删除顽固快捷方式

1. 问题缘起&#xff1a;那些删不掉的“幽灵”快捷方式 你有没有遇到过这种情况&#xff1f;在Windows的文件资源管理器左侧导航栏&#xff0c;或者右键菜单的“发送到”列表里&#xff0c;总是挂着几个早已卸载软件的快捷方式。它们像顽固的“幽灵”一样&#xff0c;既占地方又…

作者头像 李华
网站建设 2026/8/12 17:18:25

苹果评级降至五年最低,折叠屏iPhone能否拯救硬件利润率下滑困局?

苹果评级下调&#xff0c;市场悲观情绪加速聚集 这两日&#xff0c;苹果的情况颇为引人关注&#xff0c;华尔街对它的悲观情绪正加速聚集。继KeyBanc上月下调评级后&#xff0c;杰富瑞又将苹果评级降至“跑输大盘”&#xff0c;目标价下调至263.66美元。目前&#xff0c;给予苹…

作者头像 李华
网站建设 2026/8/12 17:17:49

逆向工程入门:使用x32dbg实战破解CrackMe程序Acid Burn

1. 项目概述&#xff1a;逆向工程入门与CrackMe的独特价值 如果你对软件内部运作机制充满好奇&#xff0c;总想弄清楚一个程序在点击“确定”按钮后到底做了哪些判断&#xff0c;那么逆向工程就是你打开这扇门的钥匙。而CrackMe&#xff0c;正是为学习逆向工程量身定做的“练习…

作者头像 李华
网站建设 2026/8/12 17:16:59

15.RK3588最高运行性能配置

1.查询npu版本rootATK-DLRK3588:cat /sys/kernel/debug/rknpu/version RKNPU driver: v0.9.82.查询npu的负载rootATK-DLRK3588:cat /sys/kernel/debug/rknpu/load NPU load: Core0: 0%, Core1: 0%, Core2: 0%,3.显示或者设置NPU、CPU、DDR运行频率scaling_frequence.shchip…

作者头像 李华
网站建设 2026/8/12 17:15:46

AI技术术语解析:从LLM、RAG到Agent,一文读懂大模型核心概念与应用

1. 引言&#xff1a;当技术黑话成为交流壁垒 最近在几个技术社区和项目讨论区里&#xff0c;我经常看到一种现象&#xff1a;大家讨论AI项目或者分享经验时&#xff0c;会不自觉地蹦出一些“行话”。这些词&#xff0c;圈内人一听就懂&#xff0c;甚至觉得是“专业”的体现&…

作者头像 李华