当前位置: 首页 > news >正文

图片懒加载、无限滚动加载、监听元素进入视口加载数据。「IntersectionObserver」

在 Vue 中,我们可以利用 IntersectionObserver API 来检测元素是否进入或离开视口,从而实现懒加载、无限滚动、触发动画等效果。下面简单介绍几种常见的应用场景和使用方式:

1. 懒加载图片

借助 IntersectionObserver,我们可以监听图片元素何时进入视口。通常的做法是在组件中设置一个初始的“加载中”图片,当目标图片进入视口时,再将真实的图片地址赋值给 img 标签的 src 属性。例如:

<template>
  <img
    class="lazy-image"
    :src="loadingImage"
    :data-src="realSrc"
    alt="图片描述"
  />
</template>

<script>
export default {
  props: {
    realSrc: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      loadingImage: '/assets/loading.png'
    }
  },
  mounted() {
    const img = this.$el;
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          img.src = img.dataset.src;
          observer.unobserve(img);
        }
      });
    }, {
      threshold: 0.25 // 当图片有25%进入视口时触发回调
    });
    observer.observe(img);
  }
}
</script>

这样只有当图片进入视口时才会加载真实图片,节省带宽并加快首屏渲染。

2. 无限滚动加载

在列表或内容较多的页面中,可以在底部放置一个“哨兵”元素。当该元素进入视口时,就触发数据加载的逻辑。示例代码如下:

<template>
  <div class="list-container">
    <div v-for="item in items" :key="item.id" class="list-item">
      {{ item.content }}
    </div>
    <!-- 哨兵元素 -->
    <div ref="loadMore" class="load-more">加载中...</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [],
      totalCount: 100,
      observer: null
    }
  },
  mounted() {
    this.loadData(); // 初始加载部分数据
    this.observer = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting && this.items.length < this.totalCount) {
        this.loadData();
      }
    });
    this.observer.observe(this.$refs.loadMore);
  },
  beforeDestroy() {
    this.observer && this.observer.disconnect();
  },
  methods: {
    loadData() {
      // 模拟异步加载数据
      setTimeout(() => {
        const newItems = Array.from({ length: 10 }, (_, index) => ({
          id: this.items.length + index + 1,
          content: `第 ${this.items.length + index + 1} 项`
        }));
        this.items = [...this.items, ...newItems];
      }, 500);
    }
  }
}
</script>

当“加载中…”的哨兵元素进入视口时,就会自动触发 loadData() 方法,达到无限滚动加载的效果。

3. 自定义指令封装

你还可以将 IntersectionObserver 封装为 Vue 自定义指令,使其在多个组件中复用。一个简单的指令示例:

// lazyload.js
export default {
  inserted(el, binding) {
    const options = {
      threshold: 0.1
    };
    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          el.src = binding.value;
          observer.unobserve(el);
        }
      });
    }, options);
    observer.observe(el);
  }
}

在 main.js 中全局注册后,即可在模板中直接使用:

<template>
  <img v-lazyload="'https://example.com/real-image.jpg'" src="/assets/loading.png" alt="图片">
</template>

这种方式封装后可以让代码更加模块化和复用。

总结

IntersectionObserver API 提供了一种高效、异步监听元素可见性的方案,在 Vue 中常用于:

  • 图片懒加载(减少首屏加载时间)
  • 无限滚动加载(改善用户体验)
  • 触发进入视口动画或数据加载

使用时注意在组件销毁前断开观察器,避免内存泄漏。通过合理配置 thresholdrootMargin,你可以灵活控制回调触发的时机,从而达到更佳的性能优化效果。

http://www.dtcms.com/a/108600.html

相关文章:

  • scala编程语言
  • 服务器数据恢复—Raid6阵列硬盘故障掉线,上层虚拟机数据如何恢复?
  • linux-firewalld防火墙允许端口
  • 【SLAM经典算法详解】Ubuntu 20.04部署LeGO-LOAM:从环境配置到KITTI适配,解决常见编译错误
  • 从零开发美颜SDK:美颜滤镜API的核心技术与实现
  • 多视图几何--立体校正--Fusiello方法
  • CMake学习--如何在CMake中编译静态库、动态库并在主程序中调用
  • rag精细化测试
  • 论坛系统的测试
  • win10 快速搭建 lnmp+swoole 环境 ,部署laravel6 与 swoole框架laravel-s项目1
  • Docker in Docker(Dind)
  • 深入解析 Git Submodule:从基础到高级操作指南
  • 电子电气架构 --- 控制器级架构
  • 基于HTML5的拖拽排序功能实现详解
  • Dify接口api对接,流式接收流式返回(.net)
  • Java迭代器【设计模式之迭代器模式】
  • C++ 中的类型处理与类型别名(二十六)
  • 车辆选择解决方案
  • 5.模型训练-毕设篇3
  • 字节跳动 UI-TARS 汇总整理报告
  • 核桃派2B:opencv python的 Canny findContours得到两个非常接近的轮廓,角点有几个像素的差距,如何处理?
  • 使用 Flutter 制作地图应用
  • 封装一套通用echats
  • 电子电气架构 --- 域控制器和EE架构关系
  • 时间字段前端VO接收用String,后端用Date
  • 防火墙和端口开关
  • Kafka和RocketMQ零拷贝对比
  • ABeam 德硕 | 中国汽车市场(2)——新能源车的崛起与中国汽车市场机遇与挑战
  • nuxt3 部署到服务器配置
  • 关于 数据库表关联查询(JOIN) 和 子查询(Subquery) 的详细对比,包括定义、语法、优缺点、使用场景及示例代码,并以表格总结关键差异