什么叫事件中心
- 一个事件可以满足监听 (.$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)
}
}