全局事件总线快速入门
- 概念
- 基本概念(是什么?)
- 核心概念
- 核心特性和优势(有什么用?)
- 解决了什么问题?
- 主要优势是什么?
- 案例演示?
- 传递数据-案例演示
- 传递事件-案例演示
- 与pinia有什么区别?
概念
基本概念(是什么?)
Vue全局事件总线
是一种在Vue.js应用程序中进行组件之间通信的机制。它基本上是一个Vue实例,用于在应用程序的不同组件之间传递事件和数据。
核心概念
vue
进行组件之间通信的机制全局事件总线的工作原理是
,你可以在一个组件中触发一个自定义事件,然后在其他组件中监听这个事件并执行相应的操作。这使得不同组件之间可以相互通信,而不必通过props或其他复杂的方法来传递数据。
核心特性和优势(有什么用?)
解决了什么问题?
- 解决父子组件之间或不直接关联的组件之间的通信问题。
主要优势是什么?
- 如果你只需要在不同组件之间传递一些临时数据或触发一些简单的事件,全局事件总线足够,因为它比较轻量且易于使用。适用于简单的组件通信需求。
案例演示?
传递数据-案例演示
当你需要在Vue.js应用程序中使用全局事件总线时,通常的做法是将全局总线$bus挂载到vue原型对象上
,并在需要时在组件中使用它来触发和监听事件。以下是一个简单的全局事件总线示例:
首先,在你的Vue.js应用程序中注册一个全局事件总线,你可以在main.js或类似的入口文件中添加以下代码:
import Vue from 'vue'
import App from './App.vue'
import router from '@/routers/router'Vue.config.productionTip = falsenew Vue({router,render: h => h(App),beforeCreate() {// 挂载全局事件总线到vue原型对象上Vue.prototype.$bus = this}
}).$mount('#app')
创建路由表router.js文件添加以下内容:
//作用是将指定的路由地址切换成对应的模块
// eslint-disable-next-line no-unused-vars
import Router from "vue-router"
// eslint-disable-next-line no-unused-vars
import Vue from "vue"
//在Vue中加载路由模块
Vue.use(Router)const routes = [// 进入vue项目默认进入登录页面{path: "/",redirect: "/HelloWord"},{path: "/HelloWord",component: () => import("@/components/HelloWorld.vue"),meta: {skipAuthCheck: true // 添加一个标记,表示不需要进行身份验证检查}},{path: "/index",component: () => import("@/components/child.vue"),meta: {skipAuthCheck: true // 添加一个标记,表示不需要进行身份验证检查}},
]const router = new Router({routes
});// 导出vue路由表
export default router;
现在,你可以在任何组件中使用this.$bus
来触发事件和监听事件。例如,假设你有两个组件,一个是触发事件的组件,另一个是监听事件的组件。
在触发事件的组件中:
<!-- eslint-disable vue/multi-word-component-names -->
<template><div class="child">{{msg}}</div>
</template><script>
export default {data() {return {msg: "小米加步枪",};},mounted() {console.log("进入child");// 组件挂载时触发自定义事件 传递数据this.msgthis.$bus.$emit('message-sent', this.msg);},
};
</script>
在监听事件的组件中:
<script>
<template><div class="hello"><router-link to="/index"><button @click="sendMessage">购物</button></router-link></div>
</template><script>
// 导入传递组件
import childComponent from '@/components/child.vue';
export default {name: 'HelloWorld',components: {// eslint-disable-next-line vue/no-unused-componentschildComponent,},methods: {sendMessage() {//监听一个自定义事件并处理this.$bus.$on('message-sent',(message) => {console.log(message);this.receivedMessage = message;})},}
}
</script>
在这个示例中,当用户在触发事件的组件中点击按钮时,它会触发名为"message-sent"的自定义事件,并将消息数据传递给监听事件的组件,后者在接收到事件后更新数据。
这是一个简单的全局事件总线示例,用于在Vue.js应用程序中进行组件之间的通信。你可以根据自己的需求扩展这个模式来实现更复杂的通信。
传递事件-案例演示
当你需要在Vue.js应用程序中传递自定义事件时,你可以使用Vue的自定义事件机制。以下是一个示例,演示了如何在父组件中触发自定义事件,并在子组件中监听和处理该事件:
首先,创建一个父组件(例如,Parent.vue):
<template><div><button @click="sendEvent">触发自定义事件</button><Child @custom-event="handleCustomEvent" /></div>
</template><script>
import Child from './Child.vue';export default {components: {Child,},methods: {sendEvent() {// 触发自定义事件,并传递数据this.$emit('custom-event', '这是自定义事件的数据');},handleCustomEvent(data) {// 处理从子组件接收到的事件数据console.log('接收到自定义事件:', data);},},
};
</script>
在上面的代码中,父组件通过this.$emit
触发了一个名为"custom-event"的自定义事件,并传递了一些数据。
然后,创建一个子组件(例如,Child.vue):
<template><div><p>子组件</p></div>
</template><script>
export default {mounted() {// 在子组件中监听自定义事件this.$parent.$on('custom-event', this.handleCustomEvent);},beforeDestroy() {// 在销毁子组件之前,取消对事件的监听this.$parent.$off('custom-event', this.handleCustomEvent);},methods: {handleCustomEvent(data) {// 处理父组件触发的自定义事件console.log('子组件接收到自定义事件:', data);// 可以在这里执行子组件的逻辑},},
};
</script>
在子组件中,我们使用this.$parent
(vue用于访问父组件实例的特定属性)来访问父组件,并使用$on
方法来监听父组件触发的自定义事件。在beforeDestroy
生命周期钩子中,取消对事件的监听以避免内存泄漏。
补充:
如果在路由跳转后你不想销毁之前的component可以使用<keep-alive></keep-alive>标签保持组件活跃
<keep-alive><router-view></router-view>
</keep-alive>
现在,当父组件中的按钮被点击时,它将触发自定义事件,子组件将监听并处理这个事件,从而实现了事件的传递和处理。
这个示例演示了在Vue.js中传递自定义事件的基本模式,你可以根据需要扩展它来满足更复杂的组件通信需求。
与pinia有什么区别?
- 全局事件总线和Pinia在数据传递的方式上不同:
-
全局事件总线:
数据或事件通常是临时存储在内存中的
,只在组件之间传递,但不会长期保存。当一个组件触发事件时,其他组件可以监听并获取这些事件的数据
,但这些数据不会在组件之间共享持久状态。 -
Pinia:Pinia是一个状态管理库,它允许你在应用程序中定义和管理全局状态。
Pinia的数据存储是持久的,保存在内存中,以供应用程序中的**所有组件**访问
。这意味着你可以在不同组件之间共享和维护持久状态,而不仅仅是短期的事件数据。
所以,Pinia更适合需要长期共享和管理状态的场景,而全局事件总线更适用于短期的、组件之间的临时数据传递。你可以根据项目的具体需求选择合适的方法。