EventBus

什么叫事件中心

  • 一个事件可以满足监听 (.$on),触发 (.$emit),取消监听(.$off)那他就可以叫事件中心
  • 所以一个new vew()可以构成一个实践中心

如何使用EventBus

  • 在data里面声明一个evetBus
  • 在最外层组件的属性上加一个provide属性
data(){
  return {
    eventBus: new Vue()
  }
},
provide () {
  return {eventBus: this.eventBus}
},
  • 然后只需要在子组件或孙子组件注入,那么该组件就能访问到这个事件中心了
inject:['eventBus'],  //注入
mounted() {
    //监听eventbus
  this.eventBus.$on('update:selected',(name,vm)=>{
    let headLeft = this.$el.getBoundingClientRect().left
    let {width,left} = vm.$el.getBoundingClientRect()
    this.$refs.line.style.width = width + 'px'
    this.$refs.line.style.left = left-headLeft +'px'
  })
},
  • 需要注意的是,事件中心出发的事件和vue原生的事件是不一样的,不能使用@绑定在html标签里面

一个完整的例子

  • 爷爷组件注册eventBus,并触发事件
  • this.$options.name:组件的name,this.name:组件的data或prop的name
data(){
  return {
    eventBus: new Vue()
  }
},
provide () {
  return {eventBus: this.eventBus}
},
mounted() {
  this.$children.forEach(vm=>{//父组件的儿子
    if (vm.$options.name === 'WheelTabsHead'){
      vm.$children.forEach(childVm=>{ //父组件的孙子
        if (childVm.$options.name === 'WheelTabsItem' && childVm['name'] === this.selected){
          //update:selected触发事件
          this.eventBus.$emit('update:selected', this.selected,childVm)
        }
      })
    }
  })
},
  • 儿子组件使用
inject:['eventBus'],//注入事件
mounted() {
    //监听update:selected事件
  this.eventBus.$on('update:selected',(name,vm)=>{
    let headLeft = this.$el.getBoundingClientRect().left
    let {width,left} = vm.$el.getBoundingClientRect()
    this.$refs.line.style.width = width + 'px'
    this.$refs.line.style.left = left-headLeft +'px'
  })
},
  • 孙子组件使用
created: function () {
    //监听update:selected事件
  this.eventBus.$on('update:selected', (name) => {
    this.active = this.name === name
  })
  console.log(this.name + this.disabled)
},
methods:{
  changeSelected(){
    if (this.disabled === true){return}
    //触发update:selected事件,传值
    this.eventBus.$emit('update:selected',this.name,this)
  }
}

你可能感兴趣的:(EventBus)