IntersectionObserver vue3 實(shí)現(xiàn)圖片懶加載

<template>
  <div class="container">
    <div class="sunshine" v-for="(item) in list" :key="item.tid">
      <img :data-src="item.src" :ref="setItemRef" />
      <span>{{ item.text }}</span>
    </div>
  </div>
</template>

<script setup>
  import { onMounted, ref, nextTick } from 'vue'
  const list = ref([
    {
      src: require(`../../assets/logo.png`),
      tid: 0,
      text: `item0`
    },
    {
      src: require(`../../assets/dog.jpg`),
      tid: 1,
      text: `item1`
    },
    {
      src: require(`../../assets/user.png`),
      tid: 2,
      text: `item2`
    }
  ]) // 列表

  const observeImgs = () => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(item => {
        console.log(item.isIntersecting);
        if (item.isIntersecting) {
          // 可見(jiàn)
          item.target.src = item.target.dataset.src //賦值data-src 給src
          delete item.target.dataset.src //刪除data-src
          io.unobserve(item.target) // 取消觀察
        }
      })
    })
    //循環(huán)觀察dom
    imgsRef.value.forEach(item => {
      io.observe(item)
    });
  }
  const imgsRef = ref([])
  const setItemRef = el => {
    if (el) {
      imgsRef.value.push(el)
    }
  }

  onMounted(async () => {
    nextTick(() => {
      observeImgs()
    })
  })
</script>

<style lang="scss" scoped>
.container {
  background: #ccc;
  height: 100vh;
  overflow: auto;
}
.sunshine {
  display: flex;
  align-items: center;
  justify-content: center;
  img {
    height: 400px;
  }
}
</style>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容