整体逻辑:
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 //是就显示图片}},)}}