# 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>
最后更新: 8/16/2021, 3:47:58 PM