vue:组件通信

props / $emit

只能适合父子组件通信;不适用跨层组件通信

<!-- Parent.vue -->
<template>
    <!-- custom-event -->
    <ChildComponent :message="parentMessage" @custom-event="handleEvent" />  
</template>

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

    export default {
        data() {
            return {
                parentMessage: '父级数据'
            };
        },
        methods: {
            handleEvent(data) {  // handleEvent
                console.log(data);
            }
        },
        components: {
            ChildComponent
        }
    };
</script>

<!-- ChildComponent.vue -->
<template>
<p @click="sendEvent">{{ message }}</p>     <!-- sendEvent事件 -->
</template>

<script>
    export default {
        props: {
            message: {
                type: String,
                required: true
            }
        },
        methods: {
            sendEvent() {
                this.$emit('custom-event', '子组件数据');  // $emit
            }
        }
    };
</script>

provice / inject

适合跨层级组件通信;它和mitt的区别是,inject 更适用于有嵌套关系的组件间通信

优点:避免了通过多层 props 传递数据的繁琐,使得组件间的数据流动更加清晰和灵活

缺点:增加了组件之间的耦合性;滥用会使项目难以维护

<!-- GrandParent.vue -->
<template>
    <ParentComponent />
</template>

<script>
    import ParentComponent from './ParentComponent.vue';

    export default {
        provide() {  // provide
            return {
                message: 'Hello from GrandParent'  
            };
        },
        components: {
            ParentComponent
        }
    };
</script>

<!-- ParentComponent.vue -->
<template>
    <ChildComponent />
</template>

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

    export default {
        components: {
            ChildComponent
        }
    };
</script>

<!-- ChildComponent.vue -->
<template>
    <p>{{ message }}</p>
</template>

<script>
    export default {
        inject: ['message']  // inject
    };
</script>

EventBus/mitt

通过发布订阅的方式实现跨组件的事件通信;适用于无直接关系的组件间通信;

使用 mitt 作为示例(因为 EventBus 是 Vue 2 中的一个非正式模式,而 mitt 是一个轻量级的替代方案)

// VUE3
// npm install mitt

// event-bus.js  
import mitt from 'mitt';  
export const EventBus = mitt();



// 组件A
<script>  
import { EventBus } from './event-bus';  
  
export default {  
  methods: {  
    sendDataToB() {  
      EventBus.emit('data-to-b', 'Hello from A!');  
    }  
  }  
}  
</script>


// 组件B
<script>  
import { EventBus } from './event-bus';  
  
export default {  
  mounted() {  
    EventBus.on('data-to-b', (data) => {  
      console.log(data); // 输出: Hello from A!  
    });  
  },  
  beforeDestroy() {  
    // 组件销毁前移除监听器  
    EventBus.off('data-to-b');  
  }  
}  
</script>
// VUE2
// main.js
import Vue from 'vue';
 
// 创建一个新的Vue实例作为事件总线
const bus = new Vue();
 
// 将事件总线挂载到Vue的原型链上,这样在任何组件中都可以通过this.$bus来访问
Vue.prototype.$bus = bus;
 



// ComponentA.vue
export default {
  methods: {
    sendMessage() {
      // 使用$emit触发事件,事件名为"eventName",参数为"message"
      this.$bus.$emit('eventName', 'message');
    }
  }
}

// ComponentB.vue
export default {
  mounted() {
    // 使用$on监听事件
    this.$bus.$on('eventName', (message) => {
      console.log(message); // 输出:message
    });
  },
  beforeDestroy() {
    // 一定要在组件销毁前移除事件监听,防止内存泄露
    this.$bus.$off('eventName');
  }
}

mitt 是事件发射器库,用于跨组件通信;inject 是 Vue.js 框架的选项,用于跨层级组件通信。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值