(二十六)、全局事件总线 (兄弟组件)
1.全局事件分析
$ emit是触发、$ on是绑定。
兄弟组件可以借助全局事件总线进行数据联系
- 都能够被全部组件能看得到
- 支持被绑定事件
满足上面的条件只能是 vm。因为vm被vc继承,放在vm上就能够实现共享。且每一个组件的vc都是经过一次extend(),所以每一个vc都是不一样的。只能放在vm上了。
1. $on('绑定的事件名',触发谁) 绑定自定义事件 2. $emit('触发的事件名',参数) 自定义分发事件 3. $off('解绑的事件名') 解绑自定义监视监听 4. $once('绑定的事件名',触发谁) 绑定事件监听,但只能处理一次
2.全局事件 $bus
(1).Vue原型数据被所有人共享
提示:放在vue的原型上的数据谁都能看的到 Vue.prototype.x=vvv
我们希望越早放数据越好,所以我们想到main.js
import Vue from 'vue' // 引入阉割版本的vue import App from './App.vue' // 引入App.vue组件 Vue.config.productionTip = false; Vue.prototype.p=200; // eg: 原型上添加p值为200 new Vue({ render:h=>h(App) }).$mount('#app');
App.vue
<template> <div class="app"> <h2>我是App组件</h2> <Demo1/> <Demo2/> </div> </template> <script> import { watch } from 'vue' // TODO: 引入组件 import Demo1 from './components/Demo1.vue' import Demo2 from './components/Demo2.vue' export default { name: "APP", // TODO: 注册组件 components:{ Demo1, Demo2, }, data() { return { name:'jsxs' } }, watch:{ name:{ immediate:true, handler(){ console.log(this) } } } } </script> <style> .app { background-color: brown; padding: 10px; } </style>
(2).在Vue原型上存放Vue的实列
利用main.js的生命周期钩子函数帮我们存放Vue的实列
import Vue from 'vue' // 引入阉割版本的vue import App from './App.vue' // 引入App.vue组件 Vue.config.productionTip = false; new Vue({ beforeCreate(){ Vue.prototype.p=this; }, render:h=>h(App) }).$mount('#app');
我们可以在所有的组件中获取到属性p 也就是对应的Vue实列
官方推荐我们使用 $bus去替换掉属性p也就是如下。
- $ bus: 并不是Vue自带的,不像$emit等是Vue自带的
import Vue from 'vue' // 引入阉割版本的vue import App from './App.vue' // 引入App.vue组件 Vue.config.productionTip = false; new Vue({ beforeCreate(){ Vue.prototype.$bus=this; // 1.安装事件总线 }, render:h=>h(App) }).$mount('#app');
3.全局事件总线 (Demo1接受Demo2的数据)
main.js
import Vue from 'vue' // 引入阉割版本的vue import App from './App.vue' // 引入App.vue组件 Vue.config.productionTip = false; new Vue({ beforeCreate(){ Vue.prototype.$bus=this; }, render:h=>h(App) }).$mount('#app');
App.vue
<template> <div class="app"> <h2>我是App组件</h2> <Demo1/> <Demo2/> </div> </template> <script> import { watch } from 'vue' // TODO: 引入组件 import Demo1 from './components/Demo1.vue' import Demo2 from './components/Demo2.vue' export default { name: "APP", // TODO: 注册组件 components:{ Demo1, Demo2, }, } </script> <style> .app { background-color: brown; padding: 10px; } </style>
Demo1.vue: 接受数据
发送数据用$on进行绑定事件
mounted() { this.$bus.$on('A',this.demo1); // 假如demo2被触发,我们就调用demo1 },
<template> <div class="demo1"> <h2>我是Demo1</h2> <h2>{{username1}}</h2> </div> </template> <script> export default { name: "Demo1", data() { return { username1:'demo1', } }, methods: { demo1(x){ this.username1=x; } }, mounted() { this.$bus.$on('A',this.demo1); // 假如demo2被触发,我们就调用demo1 }, } </script> <style> .demo1 { background-color: antiquewhite; } </style>
Demo2.vue: 发送数据
接受消息用$emit
$emit 是触发 $on是绑定 methods: { send_data(){ this.$bus.$emit('A',this.username2); } },
<template> <div class="demo2"> <h2>我是Demo2</h2> <button @click="send_data">点我切换数据</button> </div> </template> <script> export default { name: "Demo2", data() { return { username2:'demo2', } }, methods: { send_data(){ this.$bus.$emit('A',this.username2); } }, } </script> <style> .demo2 { background-color: rgb(12, 196, 116); } </style>
未点击按钮
点击按钮之后
4.全局事件总线(双向发送数据)
main.js
import Vue from 'vue' // 引入阉割版本的vue import App from './App.vue' // 引入App.vue组件 Vue.config.productionTip = false; new Vue({ beforeCreate(){ Vue.prototype.$bus=this; }, render:h=>h(App) }).$mount('#app');
App.vue
<template> <div class="app"> <h2>我是App组件</h2> <Demo1/> <Demo2/> </div> </template> <script> import { watch } from 'vue' // TODO: 引入组件 import Demo1 from './components/Demo1.vue' import Demo2 from './components/Demo2.vue' export default { name: "APP", // TODO: 注册组件 components:{ Demo1, Demo2, }, data() { return { name:'jsxs' } }, watch:{ name:{ immediate:true, handler(){ console.log(this) } } } } </script> <style> .app { background-color: brown; padding: 10px; } </style>
Demo1.vue
<template> <div class="demo1"> <h2>我是Demo1</h2> <h2>{{username1}}</h2> <button @click="send_data2">点击我发送数据到Demo2</button> </div> </template> <script> export default { name: "Demo1", data() { return { username1:'demo1', } }, methods: { demo1(x){ this.username1=x; }, // 发送消息到demo1 send_data2(){ console.log('xxxxxxxxx') this.$bus.$emit('B',this.username1); } }, // 接受demo2传递过来的日记 mounted() { this.$bus.$on('A',this.demo1); // 绑定A事件,假如A被触发。就调用demo1这个方法 }, } </script> <style> .demo1 { background-color: antiquewhite; } </style>
Demo2.vue
<template> <div class="demo2"> <h2>我是Demo2</h2> <button @click="send_data">点我切换数据</button> <h2>{{username2}}</h2> </div> </template> <script> export default { name: "Demo2", data() { return { username2:'demo2', } }, // 发送数据到demo1 methods: { demo2(x){ this.username2=x; }, // 发送数据 send_data(){ this.$bus.$emit('A',this.username2);// 触发A事件 并传递参数 } }, // 接受数据 mounted() { this.$bus.$on('B',this.demo2) //绑定b事件,假如b事件被触发就调用demo2这个方法 }, } </script> <style> .demo2 { background-color: rgb(12, 196, 116); } </style>