开发中遇到需要做懒加载的,所以vue-lazyload走起
安装和引入没什么好说的
yarn add vue-lazyload
//main.js 里引入
import VueLazyload from 'vue-lazyload'Vue.use(VueLazyload, { preLoad: 1.2, error: require('@/assets/image/error.png'), loading: require('@/assets/image/loading.png'), attempt: 1})
使用很简单,根据文档,在需要做懒加载的地方,直接使用
// img-card.vue
<div v-lazy-container="{ selector: 'img' }"> <img ref="lazyimg" :data-src="img_from_data" :data-loading="loadingImg" :data-error="errorImg" :key="key" /></div>
//loadingImg, errorImg对应加载中和加载失败的图片
到这里就可以生效了,然后我遇到一个需求,就是加载中,需要加一个loading效果,所以需要判断加载状态,文档是这么描述的:
Vue.use(vueLazy, {
adapter: {
loaded ({ bindType, el, naturalHeight, naturalWidth, $parent, src, loading, error, Init }) {
// do something here
},
loading (listender, Init) {...},
error (listender, Init) {...}
}
})
但是直接在main.js里这样改,显然是不好的,因为不止一个地方用到懒加载,loaded里获取的加载状态不可能对应到所有的情况,所以只能在需要用到懒加载的地方使用(比如img-card.vue里)。
然后就陷入困境了。
最后试了很多写法,得到这样一个方法:通过拿到img的dom元素,获取它的lazy属性(有三个值,laoding,loaded,error),来判断图片是否加载完成
mounted() { this.setLoadingImg()},
methods: {
// listLoading 字段控制加载动画,如果懒加载是laoding,那就一直执行动画
setLoadingImg() { let timer = null let state = '' // 循环获取懒加载图片的加载状态,加载完成或失败的,都取消laoding动画 // 由于是懒加载,不在可视区的图片会一直loading,影响性能,所以加一个setTimeout,
//手动清除定时器 timer = setInterval(() => { state = this.$refs.lazyimg && this.$refs.lazyimg.getAttribute('lazy') if (state == 'loaded' || state == 'error') { clearInterval(timer) this.listLoading = false } }, 100) setTimeout(() => { clearInterval(timer) this.listLoading = false }, 1000) }}
算是解决了需求