背景
我最近在练习Vue项目的时候使用better-scrollJavaScript库发现一个问题。
使用better-scroll很容易出现,DOM渲染还没有完成better-scroll对象就已经完成了初始化,在计算高度时一些图片都还没有加载完成。这样就会造成滚动条不能滚动显示所有内容!
解决的方法有在当前页面图片加载完成后更新一次滚动条。
但是很多时候图片所在的组件离调用更新滚动条的组件会相隔很多组件,这样让我们在图片完成加载时发布事件需要进过很繁琐的传递才能将事件传递给调用关系滚动条的组件。
上图,图片保存在goodslistitem组件中,如果使用this.$emit()来发布事件然后经过goodslist组件到home组件,然后再在home组件中拿到scroll组件实例并调用其更新滚动条的方法。这样操作会显得非常繁琐。
解决方法:
- 使用vuex保存状态
- 使用事件总线
vuex最好不要随便使用,所以这里我们使用事件总线来管理发布的事件。
这里我们使用事件总线在goodslistitem组件中图片更新完成之后使用事件总线发布事件,然后直接在home组件中监听该事件,并在该事件下调用scroll组件中的更新滚动条的方法。这样会简单很多!
下面让我们来看看事件总线怎么使用!
vue事件总线
事件总线的初始化
初始化有两种方式
封装成模块
封装初始化事件总线然后在需要使用的地方调用初始化时间总线的模块
// eventbus.js
import Vue from 'vue'
export const EventBus = new Vue()
全局初始化事件总线
在main.js文件中
// main.js
Vue.prototype.$EventBus = new Vue()
发送事件
这里以全局初始化事件总线的例子来发送事件
与上面图片例子想联系。我们在goodslistitem组件中给图片标签绑定load事件在事件处理函数imgLoad中使用下面代码来发送事件
export default {
methods:{
imgLoad(){
this.$EventBus.$emit('imgLoaded')
}
}
}
接收事件
在home组件中接收事件
export default {
mounted(){
this.$EventBus.$on('imgLoaded', ()=>{
更新滚动条...
})
}
}
移除事件监听
this.$EventBus.$off('事件名') //移除指定事件
this.$EventBus.$off() //移除所有事件