记录UniApp中的图片懒加载实现

38 阅读1分钟

背景:因为最近在做一个电商项目,所有图片资源都存储在云存储上,客户经常反馈云存储流量消耗太快了。所以开发一个图片懒加载组件
定义一个组件z-lazy-load,内容如下

<template>
  <view
    :id="id"
    ref="lazyLoadContainer"
    class="lazy-load-container"
  >
    <image
      v-if="isVisible"
      :src="realSrc"
      class="real-image"
      @load="handleLoad"
    />
  </view>
</template>

<script setup>

const props = defineProps({
  class: {
    type: String,
    default: ''
  },
  src: {
    type: String,
    default: ''
  }
})
const getDomId = () => {
  return 'z-lazy-load' + Math.random().toString(36).substr(2, 15)
}
const id = getDomId()
const isVisible = ref(false)
const lazyLoadContainer = ref(null)
const realSrc = ref('')
let observer = null

// 初始化观察器
const initObserver = () => {
  const instance = getCurrentInstance()
  // #ifdef MP-WEIXIN
  observer = uni.createIntersectionObserver(instance)
  // #endif
  // #ifndef MP-WEIXIN
  observer = uni.createIntersectionObserver()
  // #endif
  observer
    .relativeToViewport({
      top: 10,
      bottom: 10
    })
    .observe(`#${id}`, ({ intersectionRatio }) => {
      if (intersectionRatio > 0) {
        isVisible.value = true
        realSrc.value = props.src
        unobserve()
      }
    })
}
// 停止观察
const unobserve = () => {
  observer?.disconnect()
  observer = null
}

onMounted(() => {
  initObserver()
})
onBeforeUnmount(unobserve)

const handleLoad = () => {
  // 图片加载完成后的处理
}
</script>

<style lang="scss" scoped>
.lazy-load-container {
  min-width: 10px;
  min-height: 10px; /* 可根据需要调整 */
  position: relative;
  width: 100%;
  height: 100%;
  .real-image{
    width: 100%;
    height: 100%;
  }
}
</style>

使用

<z-lazy-load
    :src="imgUrl"
/>