自定义hooks实现图片懒加载

1、原理

借助IntersectionObserver这个类来判断当前图片列表中的某个图片是否进入可视区域,刚开始先给src设置一个图片作为初始值,这样图片没有出现在可视区域是,只需要加载一次。将真正的图片设置在data-src属性上,当出现在可视区域时,将data-src赋值给src。

IntersectionObserver接收两个参数,第一个参数是一个回调函数,回调函数接收一个entries,是一个需要监视的元素的数组,第二个参数是一个配置项,可以配置一些属性,详情见IntersectionObserver

2、代码实现

创建文件useLazyImg.ts,编写代码如下

import { onMounted, Ref } from 'vue'

export const useLazyImg = (ref: Ref) => {
  const observer = new IntersectionObserver(callback)
  onMounted(() => {
    // 监听传入的每一个对象
    Object.keys(ref.value).forEach((e) => observer.observe(ref.value[e]))
  })
}

function callback(entries: IntersectionObserverEntry[], observer: IntersectionObserver) {
  entries.forEach(async enter => {
    // 每一个目标元素的可见性变化
    if (enter.intersectionRatio > 0) {
      const img: Element = enter.target
      const src = img.getAttribute('data-src')
      img.setAttribute('src', src!)
      observer.unobserve(img)  // 加载完成后停止监听
    }
  })
}

3、使用

在文件中引入useLazyImg并且传入图片的ref

<template>
  <div class="container">
    <img
      ref="imgRef"  // 相同的ref会变成一个数组
      v-for="(item,index) in imgList"
      :key="index"
      class="img-item" 
      src="https://img.zcool.cn/community/0196fa582abab6a84a0d304f899eaf.gif" 
      :data-src="item"
    alt="">
  </div>
</template>

<script setup lang="ts">
import '@/assets/index.less'
import { ref, reactive } from 'vue'
import { useLazyImg } from './hooks/useLazyImg'
const imgList = reactive([
  './src/assets/images/test.jpg',
  './src/assets/images/test.jpg',
  './src/assets/images/test.jpg',
  './src/assets/images/test.jpg',
  './src/assets/images/test.jpg',
  './src/assets/images/test.jpg',
  './src/assets/images/test.jpg',
  './src/assets/images/test.jpg',
  './src/assets/images/test.jpg',
  './src/assets/images/test.jpg',
])
const imgRef = ref<HTMLImageElement>()
useLazyImg(imgRef)
</script>

<style scoped>
.container{
  width: 300px;
}
.img-item{
  width: 300px;
  height: 300px;
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值