# eventbus和事件api
- 原理:通过实例化一个Vue对象( 比如bus = new Vue() )作为母线,在组件中通过事件将参数传递出去( bus.$emit(event, [...args]) ),然后在其他组件中再通过bus( 这里按照刚前面实例化Vue对象后的叫法 )来监听此事件并接受参数( bus.$on(event, callback) )。
- new Vue实例自带$on $off $emit
# bus.js
import Vue from 'vue'
const bus = new Vue()
export default bus
import Bus from './bus'
methods:{
xx(){
Bus.$emit('going')
}
}
import Bus from './bus'
Bus.$on('going',()=>{
alert('going')
})
......
beforeDestroy () {
Bus.$off('going')
},
// main.js
Vue.prototype.$bus = new Bus()
// child1
this.$bus.$on('foo', handle)
// child2
this.$bus.$emit('foo')
或者直接在vue的原型上挂载一个new Vue就好
//main.js
Vue.prototype.$bus = new Vue();
# 原理
// Bus:事件派发、监听和回调管理
class Bus{
constructor(){
// {
// eventName1:[fn1,fn2],
// eventName2:[fn3,fn4],
// }
this.callbacks = {}
}
$on(name, fn){
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(fn)
}
$emit(name, args){
if(this.callbacks[name]){
this.callbacks[name].forEach(cb => cb(args))
}
}
}
在组件销毁前一定要记得使用bus.$off写在事件监听,否则再次进入路由时触发多次on!!!
# 自定义事件api
# vm.$on
监听当前实例上的自定义事件。事件可以由 vm.$emit 触发。回调函数会接收所有传入事件触发函数的额外参数。
vm.$on('test', function (msg) {
console.log(msg)
})
# vm.$emit
触发当前实例上的事件。附加参数都会传给监听器回调。
vm.$emit('test', 'hi')
# vm.$once
监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除。
vm.$once('test', function (msg) { console.log(msg) })
# vm.$off
移除自定义事件监听器。
- 如果没有提供参数,则移除所有的事件监听器;
- 如果只提供了事件,则移除该事件所有的监听器;
- 如果同时提供了事件与回调,则只移除这个回调的监听器。
vm.$off() // 移除所有的事件监听器
vm.$off('test') // 移除该事件所有的监听器
vm.$off('test', callback) // 只移除这个回调的监听器
<template>
<div>
<div>demo</div>
<button @click='democlick'>democlick</button>
<button @click='democlick1'>democlick1</button>
<button @click='remove1'>remove1</button>
</div>
</template>
<script>
export default {
mounted(){
this.$on("fun1",this.callback)
this.$on("fun1",()=>{
console.log('fun1 f2')
})
this.$on("fun2",()=>{
console.log('fun2')
})
this.$once("fun1",()=>{
console.log('真的只会打印一次')
})
},
methods:{
democlick(){
this.$emit("fun1")
},
democlick1(){
this.$emit("fun2")
},
remove1(){
this.$off('fun1',this.callback)
},
callback(){
console.log(9999)
}
},
}
</script>
← 欣e通项目遇到的一些问题 插槽 →