本文只在个人博客和 SegmentFault 社区个人专栏发表,转载请注明出处
个人博客: https://zengxiaotao.github.io
SegmentFault 个人专栏: https://segmentfault.com/blog...
写在前面
组件是 vue 的核心部分,而组件之间通信方式是必不可少的。 父子之间的通信方式很简单,父组件通过 props 向子组件传值,而子组件通过自定义事件把数据传递回父组件,那么非父子关系组件怎么进行通信?
Vue2.x 废弃了 broadcast 和 dispatch 之后,可以通过 vuex ,还有 event bus 来解决。这里不讲 vuex ,讲起来是另外一个话题,就讲一下怎么在非父子组件之间通过 event bus 进行通信。
demo
首先我们要实现的效果是
上下分别是 foo组件和 bar 组件,它们之间是非父子关系,分别点击各自的 button ,另一个组件的 count 对应增加。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>非父子组件通信</title>
<script src="https://unpkg.com/vue@2.1.8/dist/vue.js"></script>
</head>
<body>
<div id='app'>
<foo></foo>
<hr>
<bar></bar>
</div>
</body>
</html>
以上就是这个 demo 结构。看看 js 的实现
// 注册一个空的 Vue 实例,作为 ‘中转站’
var eventBus = new Vue({})
// foo 组件
var foo = {
template: '<div><p>the count of foo is {{fooCount}}</p>' +
'<button @click="addBar">add bar\'s count</button></div>',
data: function() {
return {
fooCount: 0
}
},
methods: {
addBar: function() {
// 触发事件
eventBus.$emit('addBar')
}
},
mounted: function() {
eventBus.$on('addFoo', function(num) {
this.fooCount +=num
}.bind(this))
// 这里必须将 this 绑定在组件实例上。如果不使用 bind , 也可以使用箭头函数。
}
}
// bar 组件
var bar = {
template: '<div><p>the count of bar is {{barCount}}</p>' +
'<button @click="addFoo">add foo\'s count</button></div>',
data: function() {
return {
barCount: 0
}
},
methods: {
addFoo: function() {
// 触发事件,同时传递一个参数
eventBus.$emit('addFoo', 2)
}
},
// 在 组件创建的钩子函数中 监听事件
mounted: function() {
eventBus.$on('addBar', function() {
this.barCount++
}.bind(this))
}
}
var vm = new Vue({
el: '#app',
components: {
foo,
bar
}
})
以上就实现了一个简易的 非父子组件之间的通信方式。通过 event bus ,在一个组件创建时的钩子函数中监听 某个事件,而在需要与其进行通信的组件中触发这个函数,同时交换数据。
当然,event bus 只适于某些不复杂的场景,在需要频繁进行组件通信的情况下,还是应该尽量使用 Vuex ,不仅使用上更加简单,同时数据流的流向也会相对清晰。
全文完
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。