首页 > 编程笔记 > JavaScript笔记
Vue事件总线用法详解
在 Vue.js 中实现组件之间数据的传递,大概有以下几种方式:
还可以使用事件总线的方式和 Vuex 的 state 的属性实现任意组件之间的数据共享。接下来介绍 Vue.js 中的事件总线,并用它实现组件之间的数据共享传递。
使用事件总线,可以分三步实现。
- 通过 props 将父组件的数据传递给子组件。
- 通过 $emit 方法将子组件中的数据,通过绑定的函数传递给父组件。
- 在父组件中定义方法,通过 @(v-bind)自定义方法='自定义函数名称'传递给子组件,在子组件中可以直接调用。
- 通过 Vue.js 组件实例的 $parent、$root、$children、$refs 等属性,获取相关的组件对象。
还可以使用事件总线的方式和 Vuex 的 state 的属性实现任意组件之间的数据共享。接下来介绍 Vue.js 中的事件总线,并用它实现组件之间的数据共享传递。
Vue事件总线
事件总线又称为 EventBus,在 Vue.js 中可以使用 EventBus 来作为沟通的桥梁,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件,但由于太方便,若使用不慎,就会造成难以维护的灾难(所以由 Vuex 作为管理状态中心,将通知的概念提升为状态共享)。使用事件总线,可以分三步实现。
1) 注册事件总线
创建一个全局的 Vue.js 对象,用来充当事件总线中心,以及用来传递事件。该事件总线只能用在当前页面的组件中,也可以将这个 Vue.js 对象保存到 Vue.js 的原型属性中,从而注册一个全局的事件总线中心,代码如下:// 创建事件总线 const eventBus = new Vue(); // 注册全局事件中心 Vue.prototype.$bus = eventBus;
2) 接收事件总线
定义一个组件,使用 $on(事件名称,回调函数)方法,给指定的总线事件绑定一个函数,监听事件总线中的事件,代码如下:<!-- 第1个组件模板,显示age --> <template id="my-view1"> <div>View1 age: {{ age }}</div> </template> <script type="text/javascript"> // 创建MyView1对象 const MyView1 = { data() { return { age: 1 }; }, mounted() { // 监听bus总线中的bindEvent事件 eventBus.$on('bindEvent', user => { this.age = user.age + this.age; }); }, template: '#my-view1' }; ... </script> ...
3) 发送事件总线
在组件代码中,用$emit(事件名称,参数)方法,向事件总线中心发送一个事件,并传递参数内容,代码如下:... <script type="text/javascript"> ... const vm = new Vue({ ... methods: { publishEvent() { this.value++; // 增加value的值 // 往eventBus总线发布bindEvent事件(全局) // 使用正确的事件名(字符串形式,并且没有感叹号) // 传递一个对象作为事件的参数 eventBus.$emit('bindEvent1', { name: 'zhangsan', age: this.value }); } } }); </script> ...整合后的代码如下:
... <div id="app"> <my-view1></my-view1> <my-view2></my-view2> <button @click="publishEvent">测试</button> </div> <!-- 第1个组件模板,显示age --> <template id="my-view1"> <div>View1 age: {{ age }}</div> </template> <!-- 第2个组件模板,显示age --> <template id="my-view2"> <div>View2 age: {{ age }}</div> </template> //事件总线 const eventBus = new Vue() <script type="text/javascript"> // 创建MyView1对象 const MyView1 = { data() { return { age: 1 }; }, mounted() { // 监听bus总线中的bindEvent事件 eventBus.$on('bindEvent', user => { this.age = user.age + this.age; }); }, template: '#my-view1' }; // 创建MyView2对象 const MyView2 = { data() { return { age: 10 }; }, mounted() { // 监听bus总线中的bindEvent事件 eventBus.$on('bindEvent', user => { this.age += user.age; }); }, template: '#my-view2' }; // 创建Vue实例并挂载到页面元素上 const vm = new Vue({ el: '#app', data: { value: 1 }, components: { MyView1, MyView2 }, methods: { publishEvent() { this.value++; // 往bus总线发布bindEvent事件 eventBus.$emit('bindEvent', { name: 'zhangsan', age: this.value }); } } }); </script> ...