element中的dispatch和broadcast是对vue1.0升级到2.0中的这两个方法的重写

虽然函数名相同,但是使用方法略有不同

想了解element源码请移步链接

首先我们需要创建一个vue的项目,本章不对创建vue项目做讲解

我们需要在src目录下创建一个mixin的文件夹

在mixin文件夹放置emitter.js,此文件可直接copy下方代码,或者从element的组件源码中copy

emitter.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function broadcast (componentName, eventName, params) {
this.$children.forEach(child => {
var name = child.$options.name

if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params))
} else {
broadcast.apply(child, [componentName, eventName].concat([params]))
}
})
}
export default {
methods: {
dispatch (componentName, eventName, params) {
var parent = this.$parent || this.$root
var name = parent.$options.name

while (parent && (!name || name !== componentName)) {
parent = parent.$parent

if (parent) {
name = parent.$options.name
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(params))
}
},
broadcast (componentName, eventName, params) {
broadcast.call(this, componentName, eventName, params)
}
}
}

使用 (子传父)

在需要向父级(或者父级的父级或者更上级)传递数据或者吊起父级(同前)的子组件中引入emitter.js到当前组件的mixin中
通过事件调用this.dispatch()方法,
第一个参数是接收的组件的name,
第二个参数是接收的组件需要监听的方法
第三个参数是你需要传递过去的数据 (非必传)

传出示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
<div class="test1">
<h1>这是一个用来测试的test1组件</h1>
<h1>{{msg}}</h1>
<button @click="onClick">按钮(传递数据给父级))</button>
</div>
</template>
<script>
import Emitter from '../mixin/emitter'
export default {
name: 'test1',
mixins: [Emitter],
data() {
return {
msg: 123
}
},
methods: {
onClick() {
this.msg++
this.dispatch('home', 'message', this.msg)
}
}
}
</script>

在接受的组件通过$on监听子组件dispatch的方法
this.$on()
第一个参数是监听的方法名,第二个参数是一个回调函数,用于处理传递过来的数据
接收示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<div class="home">
<h1>这是一个用来测试的Home页面{{msg}}</h1>
<hr/>
<test1/>
</div>
</template>
<script>
import Test1 from '../components/test1'
export default {
name: 'home',
components: {
Test1,
},
data() {
return {
msg: 123
}
},
mounted() {
this.$on('message', item => {
this.msg = item
})
}
}
</script>

这样就大功告成了, 实现了跨层级的子传父就完成了

父传子,跟这个含类似用的是broadcast方法
同样需要在使用此方法的组件中引入mixins: [Emitter]

父组件使用:

1
this.broadcast('test2', 'sss', this.msg)

子组件接收(test2组件)

1
2
3
4
5
mounted() {
this.$on('sss', item => {
this.msg = item
})
}

同理,父传子也是可以跨层级的, 但是需要是有父子关系的组件才能使用,不然得不到监听

同级数据监听可以使用先将数据传递给父级,然后由父级统一派发数据

注:本帖使用的Emitter.js修改部分属性名 将componentName修改为name,不懂可以在下方留言或者自行查阅源码

附: demo源码一份 码云地址: https://gitee.com/winnerwly/vue-emitter-demo.git

:( 这个方法作者也是初学,有什么好的方法,或者我有什么不足,还请多多指教