Vue 组件通信的 12 种解决方案

目录

[1. ‌Props(父传子)‌](#1. ‌Props(父传子)‌)

[2. ‌emit(子传父)‌](#2. ‌emit(子传父)‌)

[3. ‌.sync 修饰符(双向绑定)‌](#3. ‌.sync 修饰符(双向绑定)‌)

[4. ‌Provide / Inject(祖孙组件通信)‌](#4. ‌Provide / Inject(祖孙组件通信)‌)

[5. ‌EventBus(兄弟/跨组件通信)‌](#5. ‌EventBus(兄弟/跨组件通信)‌)

[6. ‌Pinia / Vuex(全局状态管理)‌](#6. ‌Pinia / Vuex(全局状态管理)‌)

[7. ‌parent/parent/children / refs(直接访问)‌](#7. ‌parent/parent/children / refs(直接访问)‌)

[8. ‌attrs/attrs/listeners(跨代通信)‌](#8. ‌attrs/attrs/listeners(跨代通信)‌)

[9. ‌v-model(双向绑定)‌](#9. ‌v-model(双向绑定)‌)

[10. ‌root(访问根实例)‌](#10. ‌root(访问根实例)‌)

[11. ‌ref(访问子组件)‌](#11. ‌ref(访问子组件)‌)

[12. ‌mitt(事件总线)‌](#12. ‌mitt(事件总线)‌)


1. ‌**Props(父传子)**‌

  • 优点‌:简单直接,符合单向数据流原则,易于理解和维护。

  • 缺点‌:层级过深时,传递数据会变得复杂。

  • 使用实例‌:

    <child-component :user="currentUser" /> <script> export default { props: { user: { type: Object, required: true } } } </script>

2. ‌**$emit(子传父)**‌

  • 优点‌:用于子组件向父组件传递数据,使用简单,非常常见。

  • 缺点‌:如果层级过深,需层层传递,容易造成代码冗余。

  • 使用实例‌:

    <script> export default { methods: { handleClick() { this.$emit('user-updated', { name: '新名字' }); } } } </script>

    <child-component @user-updated="handleUpdate" />

3. ‌**.sync 修饰符(双向绑定)**‌

  • 优点‌:简化了双向绑定的写法,看起来更简洁。

  • 缺点‌:Vue 3 中已被废弃,不推荐使用。

  • 使用实例

    <child-component :name.sync="userName" /> <script> export default { props: ['name'], methods: { updateName() { this.$emit('update:name', '新名字'); } } } </script>

4. ‌**Provide / Inject(祖孙组件通信)**‌

  • 优点‌:适用于跨层级组件通信,无需逐层传递 props。

  • 缺点‌:非响应式,不适用于复杂状态管理。

  • 使用实例‌:

    <script> export default { provide() { return { user: this.currentUser }; } } </script> <script> export default { inject: ['user'] } </script>

5. ‌**EventBus(兄弟/跨组件通信)**‌

  • 优点‌:适用于任意组件间通信,使用简单。

  • 缺点‌:难以维护,容易造成内存泄漏,不推荐在大型项目中使用。

  • 使用实例‌:

    // eventBus.js
    import Vue from 'vue';
    export default new Vue();

    // 组件A
    EventBus.$emit('update-user', data);

    // 组件B
    EventBus.$on('update-user', (data) => { ... });

6. ‌**Pinia / Vuex(全局状态管理)**‌

  • 优点‌:适合管理全局状态,便于维护和调试。

  • 缺点‌:对于简单通信可能显得"重量级"。

  • 使用实例‌:

    // store.js
    import { defineStore } from 'pinia';
    export const useUserStore = defineStore('user', {
    state: () => ({ name: '' }),
    actions: {
    updateName(name) {
    this.name = name;
    }
    }
    });

    // 组件中使用
    const store = useUserStore();
    store.updateName('张三');

7. ‌**parent/parent/children / $refs(直接访问)**‌

  • 优点‌:直接访问组件实例,适合操作子组件方法或数据。

  • 缺点‌:破坏组件封装性,不易维护。

  • 使用实例‌:

    <child-component ref="childRef" />

    this.$refs.childRef.someMethod();

8. ‌**attrs/attrs/listeners(跨代通信)**‌

  • 优点‌:适合跨层级传递 props 和事件。

  • 缺点 ‌:需配合 inheritAttrs: false 使用。

  • 使用实例‌:

    <child-component :title="title" @click="handleClick" />

    <grand-child v-bind="$attrs" v-on="$listeners" />

9. ‌**v-model(双向绑定)**‌

  • 优点‌:简化了父子组件的双向数据绑定。

  • 缺点 ‌:需配合 definePropsdefineEmits 使用(Vue 3)。

  • 使用实例‌:

    <child-component v-model="message" /> <script setup> const props = defineProps(['modelValue']); const emit = defineEmits(['update:modelValue']);

    const updateMessage = () => {
    emit('update:modelValue', '新消息');
    };
    </script>

10. ‌**$root(访问根实例)**‌

  • 优点‌:可以访问根组件实例,适合全局状态访问。

  • 缺点‌:容易导致代码耦合,不推荐滥用。

  • 使用实例‌:

    this.$root.someGlobalData = '数据';

11. ‌**ref(访问子组件)**‌

  • 优点‌:直接访问子组件实例,适合调用子组件方法。

  • 缺点‌:破坏组件封装性。

  • 使用实例‌:

    <child-component ref="child" />

    this.$refs.child.someMethod();

12. ‌**mitt(事件总线)**‌

  • 优点‌:适用于任意组件通信,可替代 EventBus。

  • 缺点‌:需手动管理事件监听,防止内存泄漏。

  • 使用实例‌:

    // mitt.js
    import mitt from 'mitt';
    const emitter = mitt();
    export default emitter;

    // 组件A
    emitter.emit('update-user', data);

    // 组件B
    emitter.on('update-user', (data) => { ... });

相关推荐
counterxing2 小时前
我整理了一个免费开发资源目录,还做成了 CLI 和 MCP
前端·agent·ai编程
子兮曰9 小时前
Bun v1.3.14 深度解析:Image API、HTTP/3、全局虚拟存储与五十项变革
前端·后端·bun
kyriewen10 小时前
今天,百年巨头一次砍了9200人,而一个离职科学家的实话让全网睡不着觉
前端·openai·ai编程
问心无愧051310 小时前
ctf show web 入门42
android·前端·android studio
kyriewen11 小时前
老板逼我上AI,我偷偷在浏览器里跑LLaMA,省下20万API费
前端·react.js·llm
Beginner x_u11 小时前
前端八股整理(手写 02)|数组转树、数组扁平化、随机打乱一个数组
前端·数组·数组转树·数组扁平化
KaMeidebaby11 小时前
卡梅德生物技术快报|禽类成纤维细胞 FISH 实验:鸟类性别染色体基因定位技术实现与数据验证
前端·数据库·其他·百度·新浪微博
天若有情67311 小时前
前端高阶性能优化:跳出传统懒加载与预加载,基于用户行为做轻量预判加载
前端·性能优化
小小小小宇11 小时前
前端转后端:SQL 是什么
前端
张元清12 小时前
React Observer Hooks:7 种监听 DOM 而不写样板代码的方式
前端·javascript·面试