一、 效果图
二、 代码
<template>
<img
ref="imgLazy"
:data-src="dataSrc"
:src="src"
:alt="alt"
:title="title"
class="kh-img-lazy"
@error="imgErrorHandle"
>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
export default defineComponent({
name: 'KhImgLazy',
props: {
dataSrc: {
type: String,
default: ''
},
alt: {
type: String,
default: 'img'
},
title: {
type: String,
default: ''
}
},
setup() {
const IMG_LAZY = reactive({
error: require('@client/assets/imgs/common/kh_error.webp'),
src: require('@client/assets/imgs/common/kh_loading.webp'),
io: ref<any>(null),
})
return {
...toRefs(IMG_LAZY)
}
},
watch: {
dataSrc: {
deep: true,
handler: function() {
this.listenIntersection();
}
}
},
mounted() {
this.listenIntersection();
},
methods: {
/**
* @description imgErrorHandle img 错误处理函数
* @returns { void }
*/
imgErrorHandle(): void {
this.src = this.error; // img error
},
/**
* @description listenIntersection 监听交互事件
* @returns { void }
*/
listenIntersection(): void {
this.io = new IntersectionObserver((entries) => {
entries.forEach((val) => {
if (val && val.isIntersecting && val.target) {
this.src = this.dataSrc; // 赋值img src属性
// 取消监听
this.io.unobserve(this.$refs.imgLazy as HTMLBaseElement);
this.io = null;
}
})
})
// 监听 img
this.io.observe(this.$refs.imgLazy as HTMLBaseElement)
}
}
});
</script>
<style lang="less" scoped>
/** define kh-img-lazy */
.kh-img-lazy {
width: auto;
max-width: 100%;
}
</style>
三、源码下载
github地址
记得star(哈哈)