功能实现的核心思维:
- 我是用的IntersectionObserver API去实现的;
- IntersectionObserver 对象的observe() 方法向IntersectionObserver对象监听的目标集合添加一个元素。一个监听者有一组阈值和一个根, 但是可以监视多个目标元素,以查看这些目标元素可见区域的变化;
封装的图片懒加载的核心代码;
import img from "@/assets/logo.png";
let timer = null;
let observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting || entry.intersectionRatio > 0) {
!entry.target.isLoaded && showImage(entry.target, entry.target.data_src);
}
});
});
function showImage(el, imgSrc) {
const img = new Image();
img.src = imgSrc;
img.onload = () => {
el.src = imgSrc;
el.isLoaded = true;
};
}
export default {
inserted(el, binding, vnode) {
clearTimeout(timer);
el.src = img;
el.data_src = binding.value;
observer.observe(el);
const vm = vnode.context;
timer = setTimeout(() => {
vm.$on("hook:beforeDestroy", () => {
observer.disconnect();
});
}, 20);
},
update(el, binding) {
el.isLoaded = false;
el.data_src = binding.value;
},
};
需要在man.js 入口文件全局注册自定义指令;
import image from "./utils/directive/image";
Vue.directive("image", image);
在组件中使用使用自定义指令;
<template>
<div>
<div v-for="(item, index) in imgSrc" :key="index">
<img v-image="item" />
</div>
</div>
</template>
<script>
import image from "@/utils/directive/image.js";
export default {
directives: {
image: image,
},
data() {
return {
imgSrc: [
"http://img10.360buyimg.com/da/s1180x940_jfs/t1/140815/14/928/75404/5eea125aE80867bc3/540b8da207f399ca.jpg",
"http://img14.360buyimg.com/mobilecms/s280x280_jfs/t1/112324/19/2435/79507/5ea24977E08f79bb6/f2a77cbd1c74549c.jpg",
"http://img10.360buyimg.com/img/jfs/t1/117726/20/7368/88789/5ec3777cE70ffaf64/47d8f5d0310958bd.gif",
"http://img11.360buyimg.com/jdcms/s300x300_jfs/t1/127115/26/5040/311434/5eea32ffEee00881f/17dfa7f424bed8a0.jpg",
"http://img20.360buyimg.com/jdcms/s300x300_jfs/t1/56673/16/10608/172980/5d79e30dEb869e5b4/ebf71584c27d9a42.jpg",
"http://img10.360buyimg.com/da/s1180x940_jfs/t1/140815/14/928/75404/5eea125aE80867bc3/540b8da207f399ca.jpg",
"http://img14.360buyimg.com/mobilecms/s280x280_jfs/t1/112324/19/2435/79507/5ea24977E08f79bb6/f2a77cbd1c74549c.jpg",
"http://img10.360buyimg.com/img/jfs/t1/117726/20/7368/88789/5ec3777cE70ffaf64/47d8f5d0310958bd.gif",
"http://img11.360buyimg.com/jdcms/s300x300_jfs/t1/127115/26/5040/311434/5eea32ffEee00881f/17dfa7f424bed8a0.jpg",
"http://img20.360buyimg.com/jdcms/s300x300_jfs/t1/56673/16/10608/172980/5d79e30dEb869e5b4/ebf71584c27d9a42.jpg",
"http://img10.360buyimg.com/da/s1180x940_jfs/t1/140815/14/928/75404/5eea125aE80867bc3/540b8da207f399ca.jpg",
"http://img14.360buyimg.com/mobilecms/s280x280_jfs/t1/112324/19/2435/79507/5ea24977E08f79bb6/f2a77cbd1c74549c.jpg",
"http://img10.360buyimg.com/img/jfs/t1/117726/20/7368/88789/5ec3777cE70ffaf64/47d8f5d0310958bd.gif",
"http://img11.360buyimg.com/jdcms/s300x300_jfs/t1/127115/26/5040/311434/5eea32ffEee00881f/17dfa7f424bed8a0.jpg",
"http://img20.360buyimg.com/jdcms/s300x300_jfs/t1/56673/16/10608/172980/5d79e30dEb869e5b4/ebf71584c27d9a42.jpg",
],
};
},
};
</script>
<style scoped>
img {
width: 500px;
height: 500px;
}
</style>
效果演示: