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
:( 这个方法作者也是初学,有什么好的方法,或者我有什么不足,还请多多指教