周振林 周振林
首页
  • 前端文章

    • HTML
    • CSS
    • Tailwind CSS (opens new window)
    • JavaScript
    • Vue3
    • 其他
  • 学习笔记

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript》
    • 《Vue》
    • 《Git》
    • 《小程序笔记》
    • 《JS设计模式总结笔记》
  • 规范
  • Spring
  • 安装教程
  • 其他教程
  • 归真医学
  • 常用药材
  • 学习笔记
  • 经方学习心得
  • 基础
  • 虚拟化
  • Docker
  • OpenStack
  • 心情杂货
关于
收藏
  • 分类
  • 标签
  • 归档

周振林

IT界的小学生
首页
  • 前端文章

    • HTML
    • CSS
    • Tailwind CSS (opens new window)
    • JavaScript
    • Vue3
    • 其他
  • 学习笔记

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript》
    • 《Vue》
    • 《Git》
    • 《小程序笔记》
    • 《JS设计模式总结笔记》
  • 规范
  • Spring
  • 安装教程
  • 其他教程
  • 归真医学
  • 常用药材
  • 学习笔记
  • 经方学习心得
  • 基础
  • 虚拟化
  • Docker
  • OpenStack
  • 心情杂货
关于
收藏
  • 分类
  • 标签
  • 归档
  • HTML

  • CSS

  • JavaScript

  • Vue3

    • Vue3路由跳转及传参
    • 常用知识
    • Vue3组件通信13种方法
      • 1. 父组件向子组件传递数据 (Props)
      • 2. 子组件向父组件传递数据 (Emit)
      • 3. 兄弟组件通信 (Mitt)
      • 4. 透传 Attributes ($attrs)
      • 5. 模板引用 (Refs)
      • 6. 双向绑定 (v-model)
      • 7. 依赖注入 (Provide/Inject)
      • 8. 路由传参
      • 9. Vuex 状态管理
      • 10. Pinia 状态管理
      • 11. 浏览器存储
      • 12. Window 对象
      • 13. 全局属性
      • h2总结
  • 学习笔记

  • 其他

  • 前端
  • Vue3
周振林
2025-07-11
目录

Vue3组件通信13种方法

# Vue3组件通信13种方法

在 Vue 3 中,组件之间的通信是构建应用程序的关键。本指南将介绍 13 种不同的组件通信方法,从最简单到最复杂,帮助你选择最适合你需求的方式。

# 1. 父组件向子组件传递数据 (Props)

这是最基本也是最常用的通信方式。父组件通过属性向子组件传递数据。

「父组件:」

    
    <template>  
      <child :name="name"></child>  
    </template>  
      
    <script setup>  
    import { ref } from 'vue'  
    import Child from './Child.vue'  
      
    const name = ref('小明')  
    </script>  
1
2
3
4
5
6
7
8
9
10
11

「子组件:」

    
    <template>  
      <div>{{ props.name }}</div>  
    </template>  
      
    <script setup>  
    import { defineProps } from 'vue'  
      
    const props = defineProps({  
      name: {  
        type: String,  
        default: '',  
      },  
    })  
    </script>  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 2. 子组件向父组件传递数据 (Emit)

子组件可以通过触发事件的方式向父组件传递数据。

「子组件:」

   
   <template>  
     <button @click="handleClick">点击我</button>  
   </template>  
     
   <script setup>  
   import { ref, defineEmits } from 'vue'  
     
   const message = ref('来自子组件的问候')  
   const emits = defineEmits(['greet'])  
     
   const handleClick = () => {  
     emits('greet', message.value)  
   }  
   </script>  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

「父组件:」

    <template>  
      <child @greet="handleGreet"></child>  
    </template>  
      
    <script setup>  
    import { ref } from 'vue'  
    import Child from './Child.vue'  
      
    const handleGreet = (message) => {  
      console.log(message) // 输出: "来自子组件的问候"  
    }  
    </script>  
1
2
3
4
5
6
7
8
9
10
11
12

# 3. 兄弟组件通信 (Mitt)

对于兄弟组件之间的通信,我们可以使用第三方库 mitt 来实现一个简单的事件总线。

首先,安装 mitt:

    npm install --save mitt  
1

然后,在 main.js 中全局配置:

    import { createApp } from 'vue'  
    import mitt from 'mitt'  
    import App from './App.vue'  
      
    const app = createApp(App)  
    app.config.globalProperties.$bus = mitt()  
      
    app.mount('#app')  
1
2
3
4
5
6
7
8

「发送事件的组件:」

    <script setup>  
    import { getCurrentInstance } from 'vue'  
      
    const { proxy } = getCurrentInstance()  
    const sendMessage = () => {  
      proxy.$bus.emit('myEvent', '你好,兄弟')  
    }  
    </script>  
1
2
3
4
5
6
7
8

「接收事件的组件:」

    <script setup>  
    import { onMounted, getCurrentInstance } from 'vue'  
      
    const { proxy } = getCurrentInstance()  
      
    onMounted(() => {  
      proxy.$bus.on('myEvent', (message) => {  
        console.log(message) // 输出: "你好,兄弟"  
      })  
    })  
    </script>  
1
2
3
4
5
6
7
8
9
10
11

# 4. 透传 Attributes ($attrs)

$attrs 包含了父组件传递给子组件的所有属性,除了那些已经被 props 或 emits 声明的。

「父组件:」

    <template>  
      <child name="小明" age="18" hobby="篮球"></child>  
    </template>  
1
2
3

「子组件:」

    <script setup>  
    import { useAttrs } from 'vue'  
      
    const attrs = useAttrs()  
    console.log(attrs) // { age: "18", hobby: "篮球" }  
    </script>  
1
2
3
4
5
6

# 5. 模板引用 (Refs)

通过 ref,父组件可以直接访问子组件的属性和方法。

「父组件:」

    <template>  
      <child ref="childRef"></child>  
      <button @click="callChildMethod">调用子组件方法</button>  
    </template>  
      
    <script setup>  
    import { ref } from 'vue'  
    import Child from './Child.vue'  
      
    const childRef = ref(null)  
      
    const callChildMethod = () => {  
      childRef.value.someMethod()  
    }  
    </script>  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

「子组件:」

    <script setup>  
    import { defineExpose } from 'vue'  
      
    const someMethod = () => {  
      console.log('子组件方法被调用了')  
    }  
      
    defineExpose({  
      someMethod,  
    })  
    </script>  
1
2
3
4
5
6
7
8
9
10
11

# 6. 双向绑定 (v-model)

v-model 提供了一种简洁的方式来实现父子组件之间的双向数据绑定。

「父组件:」

    <template>  
      <child v-model:name="name"></child>  
    </template>  
      
    <script setup>  
    import { ref } from 'vue'  
    import Child from './Child.vue'  
      
    const name = ref('小明')  
    </script>  
1
2
3
4
5
6
7
8
9
10

「子组件:」

    <template>  
      <input :value="name" @input="updateName" />  
    </template>  
      
    <script setup>  
    import { defineProps, defineEmits } from 'vue'  
      
    const props = defineProps(['name'])  
    const emit = defineEmits(['update:name'])  
      
    const updateName = (e) => {  
      emit('update:name', e.target.value)  
    }  
    </script>  
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 7. 依赖注入 (Provide/Inject)

provide 和 inject 允许祖先组件向所有子孙组件传递数据,而不需要通过每一层组件手动传递。

「祖先组件:」

    <script setup>  
    import { provide, ref } from 'vue'  
      
    const themeColor = ref('blue')  
    provide('theme', themeColor)  
    </script>  
1
2
3
4
5
6

「子孙组件:」

    <script setup>  
    import { inject } from 'vue'  
      
    const theme = inject('theme')  
    console.log(theme.value) // 'blue'  
    </script>  
1
2
3
4
5
6

# 8. 路由传参

Vue Router 提供了多种方式在路由之间传递参数。

「通过 query 传参:」

    import { useRouter } from 'vue-router'  
      
    const router = useRouter()  
    router.push({ path: '/user', query: { id: 123 } })  
      
    // 在目标组件中  
    import { useRoute } from 'vue-router'  
      
    const route = useRoute()  
    console.log(route.query.id) // 123  
1
2
3
4
5
6
7
8
9
10

# 9. Vuex 状态管理

Vuex 是 Vue 的官方状态管理库,适用于大型应用。

    // store/index.js  
    import { createStore } from 'vuex'  
      
    export default createStore({  
      state: {  
        count: 0,  
      },  
      mutations: {  
        increment(state) {  
          state.count++  
        },  
      },  
    })  
      
    // 在组件中使用  
    import { useStore } from 'vuex'  
      
    const store = useStore()  
    console.log(store.state.count)  
    store.commit('increment')  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 10. Pinia 状态管理

Pinia 是新一代的 Vue 状态管理库,提供更简单的 API 和更好的 TypeScript 支持。

    // stores/counter.js  
    import { defineStore } from 'pinia'  
      
    export const useCounterStore = defineStore('counter', {  
      state: () => ({ count: 0 }),  
      actions: {  
        increment() {  
          this.count++  
        },  
      },  
    })  
      
    // 在组件中使用  
    import { useCounterStore } from '@/stores/counter'  
      
    const counter = useCounterStore()  
    console.log(counter.count)  
    counter.increment()  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 11. 浏览器存储

localStorage 和 sessionStorage 可以用于在不同页面或组件之间共享数据。

    // 存储数据  
    localStorage.setItem('user', JSON.stringify({ name: '小明', age: 18 }))  
      
    // 读取数据  
    const user = JSON.parse(localStorage.getItem('user'))  
1
2
3
4
5

# 12. Window 对象

虽然不推荐,但在某些场景下,可以使用 window 对象在全局范围内共享数据。

    // 设置全局数据  
    window.globalData = { message: '全局消息' }  
      
    // 在任何地方使用  
    console.log(window.globalData.message)  
1
2
3
4
5

# 13. 全局属性

Vue 3 提供了 app.config.globalProperties 来替代 Vue 2 中的 Vue.prototype,用于添加全局可用的属性。

    // main.js  
    const app = createApp(App)  
    app.config.globalProperties.$http = axios  
      
    // 在组件中使用  
    import { getCurrentInstance } from 'vue'  
      
    const { proxy } = getCurrentInstance()  
    proxy.$http.get('/api/data')  
1
2
3
4
5
6
7
8
9

# h2总结

这 13 种方法涵盖了 Vue 3 中几乎所有的组件通信场景。根据你的具体需求和应用规模,选择最合适的通信方式。

常用知识
《JavaScript教程》笔记

← 常用知识 《JavaScript教程》笔记→

最近更新
01
Tree工具类,轻松搞定树结构
07-11
02
Maven教程
07-11
03
SpringBoot集成Modbus实现设备
07-11
更多文章>
Copyright © 2019-2025 鲁ICP备19032096号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式