如何选择Vue的$emit和props与provide/inject,以及事件总线(Event Bus)

✨ 区别

在Vue.js中,我们有多种选择来在组件之间传递数据和通信,包括使用$emitpropsprovideinject以及事件总线(Event Bus)。每种方法都具有自己的优势和适用场景。

🎃 使用 $emit 和 props

  • $emit和props是Vue官方推荐的一种数据传递和通信方式。
  • 适用于父子组件之间的数据传递。
  • 通过在子组件中触发自定义事件$emit,将数据传递给父组件进行处理。
  • 父组件通过props属性明确指定接收哪些数据,并进行类型检查和默认值设置。

🌟示例:

父组件:

javascript 复制代码
<template>
  <div>
    <child-component :message="parentMessage" @custom-event="handleEvent"></child-component>
  </div>
</template>

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

export default {
  data() {
    return {
      parentMessage: 'Hello from parent',
    };
  },
  methods: {
    handleEvent(data) {
      console.log('Received data from child:', data);
    },
  },
  components: {
    ChildComponent,
  },
};
</script>

子组件:

javascript 复制代码
<template>
  <div>
    <button @click="sendMessage">Send Message to Parent</button>
  </div>
</template>

<script>
export default {
  props: ['message'],
  methods: {
    sendMessage() {
      this.$emit('custom-event', 'Hello from child');
    },
  },
};
</script>

🎃 使用 provide 和 inject

  • provide和inject可以创建一个"祖先-后代"关系的数据传递。
  • 适用于跨层级组件之间的数据传递。
  • 在祖先组件中使用provide,定义数据;在后代组件中使用inject访问这些数据。
  • 可以在整个组件树中访问数据,无需通过props一层层传递。

🌟示例:

祖先组件:

javascript 复制代码
<template>
  <div>
    <grand-child-component></grand-child-component>
  </div>
</template>

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

export default {
  provide: {
    sharedMessage: 'Hello from ancestor',
  },
  components: {
    GrandChildComponent,
  },
};
</script>

父组件:

javascript 复制代码
<template>
  <div>
    <child-component></child-component>
  </div>
</template>

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

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

子组件:

javascript 复制代码
<template>
  <div>
    <p>{{ sharedMessage }}</p>
  </div>
</template>

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

后代组件:

javascript 复制代码
<template>
  <div>
    <p>{{ sharedMessage }}</p>
  </div>
</template>

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

🎃 使用事件总线(Event Bus)

  • 事件总线(Event Bus)通过中央事件管理器实现组件间通信。
  • 适用于非父子组件之间的通信。
  • 在Vue实例中创建事件管理器,组件通过订阅和触发事件实现数据交互。
  • 可能在大型应用程序中变得难以维护。

🌟示例:

javascript 复制代码
// 创建事件总线实例
const bus = new Vue();

// 发送事件
bus.$emit('custom-event', 'Hello from emitter');

// 监听事件
bus.$on('custom-event', (data) => {
  console.log('Received data:', data);
});

✨ 选择

在选择$emitprops、provideinject,以及事件总线(Event Bus)时,考虑以下因素:

  • 数据传递关系:对于父子组件之间的数据传递,推荐使用 $emitprops。子组件通过 $emit 来触发自定义事件,并将数据传递给父组件进行处理,同时父组件通过 props 属性明确指定接收哪些数据,并进行类型检查和默认值设置。对于跨层级组件之间的数据传递,可以使用 provideinject。祖先组件使用 provide 定义数据,后代组件通过 inject 访问这些数据。而对于非父子组件之间的通信,可以考虑使用事件总线(Event Bus)机制。通过创建一个中央事件管理器,组件可以订阅和触发事件来实现数据交互。

  • 应用规模:对于较小的应用程序,简单的数据传递和通信可以选择使用 $emitprops、provideinject,或者事件总线(Event Bus)。而对于较大的应用程序,可能需要更复杂的状态管理和数据共享,可以考虑使用 Vuex 来统一管理状态。

根据组件之间的关系、应用规模和需求,我们可以选择适合的数据传递和通信方式。

相关推荐
To_OC1 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic1 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy1 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志2 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble3 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯4 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜4 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司5 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
江华森5 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http
IT_陈寒6 小时前
Redis的KEYS命令把我搞崩溃了,改用SCAN才活过来
前端·人工智能·后端