整体逻辑:
1.使用全局自定义指令创建图片懒加载指令
2.在全局自定义指令中获取图片距离顶部的高度和整个视口的高度
3.实现判断图片是否在视口内的逻辑
一、使用原生js在vue2中实现图片懒加载
1.创建dom元素,v-lazy为自定义指令,在自定义指令传入图片的url
<!-- 模拟一个循环渲染的例子 -->
<template>
<div>
<img v-lazy="imgUrl" style="width: 100px;height: 100px;display: block;" class="lazy-img" alt="">
<img v-lazy="imgUrl2" style="width: 100px;height: 100px;display: block;" class="lazy-img" alt="">
</div>
</template>
<script>
data () {
return {
imgUrl:"https://tse1-mm.cn.bing.net/th/id/OIP-C.duz6S7Fvygrqd6Yj_DcXAQHaF7?rs=1&pid=ImgDetMain",
imgUrl2:"https://img.zcool.cn/community/01df7b56de44db6ac72531cb2906b9.JPG@3000w_1l_2o_100sh.jpg",
}
</script>
2.创建自定义指令,我是将指令封装到单独的directive文件夹里,更符合实际开发场景
3.在main,js中注册全局自定义指令
import * as directive from '@/directive'
// 开始遍历注册
Object.keys(directive).forEach(key => {
Vue.directive(key, directive[key])
})
4.在directive/index.js中自定义指令中实现图片懒加载逻辑
//1.将判断逻辑封装成方法
const picIsShow = (el,binding)=>{
const windowHeight = window.innerHeight//获取视口高度
const imgTop = el.getBoundingClientRect().top//获取图片距离顶部高度
if(imgTop - windowHeight < 0){//判断是否在视口内
el.src = binding.value//将自定义指令传递来的图片url以添加属性的方式赋值给src
}
}
/**
* 2.在指令中监听窗口变化时触发懒加载
*/
export const lazy = {
inserted: function (el, binding) {
picIsShow(el,binding)
//窗口加载时
window.onload = ()=>{
picIsShow(el,binding)
}
//视口滚动事件
window.addEventListener('scroll',()=>{
picIsShow(el,binding)
})
//视口大小变化事件
window.addEventListener('resize',()=>{
picIsShow(el,binding)
})
}
}
二、使用vueuse插件的useIntersectionOberver在vue2中实现图片懒加载(超简单开发适用)
官方文档:useIntersectionObserver插件的使用
- 安装 @vueuse/core 依赖包
yarn add @vueuse/core
# 或
npm install @vueuse/core
2.引入插件
import { useIntersectionObserver } from '@vueuse/core'
3.实现
import { useIntersectionObserver } from '@vueuse/core'
export const lazy = {
inserted(el,binding){
const { stop } = useIntersectionObserver(
el,
([{ isIntersecting }], observerElement) => {
console.log('isIntersecting',isIntersecting)
if(isIntersecting){ //el元素是否在视口内
el.src = binding.value //是就显示图片
}
},
)
}
}