更新记录

1.0.0(2025-12-03) 下载此版本

  • ✨ 支持多种小程序平台和 H5
  • ✨ 基于 Observer 观察模式实现高性能懒加载
  • ✨ 支持自定义加载中和加载失败图片
  • ✨ 支持配置懒加载阈值

平台兼容性

uni-app(3.6.15)

Vue2 Vue3 Vue2插件版本 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× 1.0.0 -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟

其他

多语言 暗黑模式 宽屏模式
×

yf-lazy-image

🖼️ 图片懒加载组件

一个轻量级、高性能的图片懒加载组件,支持多种小程序平台和H5

🚀 采用 Observer 观察模式,性能极高,流畅无卡顿

📦 安装

# 通过npm安装
npm install yf-lazy-image

# 或通过uni-app插件市场安装

🚀 快速开始

基础用法

<fy-lazy-image 
  mode="aspectFill"
  :src="imageUrl" 
/>

完整示例

以下是一个完整的使用示例,展示了在不同场景下的应用:

<template>
  <view class="demo-container">
    <!-- 轮播图 -->
    <view class="carousel-section">
      <swiper class="carousel" indicator-dots circular autoplay :interval="3000" :duration="500">
        <swiper-item v-for="(item, index) in carouselList" :key="index">
          <fy-lazy-image
            class="carousel-image"
            mode="aspectFill"
            :src="item" 
            @load="onImageLoad"
            @error="onImageError"
          />
        </swiper-item>
      </swiper>
    </view>

    <!-- 横向滚动图片 -->
    <view class="horizontal-section">
      <view class="section-title">横向滚动图片</view>
      <scroll-view scroll-x class="horizontal-scroll">
        <view class="horizontal-list">
          <view class="horizontal-item" v-for="(item, index) in picList" :key="index">
            <fy-lazy-image
              class="horizontal-image"
              mode="aspectFill"
              :src="item" 
              @load="onImageLoad"
              @error="onImageError"
            />
          </view>
        </view>
      </scroll-view>
    </view>

    <!-- 纵向图片列表 -->
    <view class="vertical-section">
      <view class="section-title">纵向图片列表</view>
      <view class="vertical-list">
        <view class="vertical-item" v-for="(item, index) in verticalList" :key="index">
          <fy-lazy-image 
            class="vertical-image" 
            mode="aspectFill" 
            :src="item" 
            @load="onImageLoad"
            @error="onImageError"
          />
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 类型定义
interface ImageLoadEvent {
  width: number;
  height: number;
}

interface ImageErrorEvent {
  err: Error;
}

// 轮播图数据
const carouselList = ref<string[]>([
  'https://picsum.photos/100/200',
  'https://picsum.photos/100/201',
  'https://picsum.photos/100/202',
  'https://picsum.photos/100/203',
]);

// 横向滚动图片数据
const picList = ref<string[]>([
  'https://picsum.photos/50/50',
  'https://picsum.photos/50/51',
  'https://picsum.photos/50/52',
  'https://picsum.photos/50/53',
  'https://picsum.photos/50/54',
  'https://picsum.photos/50/55',
]);

// 纵向图片列表数据
const verticalList = ref<string[]>([
  'https://picsum.photos/80/80',
  'https://picsum.photos/80/81',
  'https://picsum.photos/80/82',
  'https://picsum.photos/80/83',
  'https://picsum.photos/80/84',
  'https://picsum.photos/80/85',
  'https://picsum.photos/80/86',
  'https://picsum.photos/80/87',
  'https://picsum.photos/80/88',
]);

// 图片加载成功事件
const onImageLoad = (event: ImageLoadEvent) => {
  console.log('图片加载成功:', event);
};

// 图片加载失败事件
const onImageError = (event: ImageErrorEvent) => {
  console.error('图片加载失败:', event);
};
</script>

<style lang="scss" scoped>
.demo-container {
  padding: 20rpx;
}

/* 轮播图样式 */
.carousel-section {
  margin-bottom: 30rpx;
}

.carousel {
  height: 400rpx;
  border-radius: 16rpx;
  overflow: hidden;
}

.carousel-image {
  width: 100%;
  height: 100%;
}

/* 横向滚动样式 */
.horizontal-section {
  margin-bottom: 30rpx;
}

.section-title {
  font-size: 32rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 20rpx;
}

.horizontal-scroll {
  white-space: nowrap;
  height: 100px;
}

.horizontal-list {
  display: inline-flex;
  padding-bottom: 10rpx;
}

.horizontal-item {
  margin-right: 16rpx;
  display: inline-block;
}

.horizontal-image {
  width: 240rpx;
  height: 180rpx;
  border-radius: 8rpx;
}

/* 纵向列表样式 */
.vertical-section {
  margin-bottom: 30rpx;
}

.vertical-list {
  display: flex;
  flex-direction: column;
}

.vertical-item,
.horizontal-item {
  margin-bottom: 16rpx;
  width: 100px;
  height: 100px;
}

.vertical-image {
  width: 100%;
  height: 300rpx;
  border-radius: 8rpx;
}
</style>

TypeScript 使用示例

在 TypeScript 项目中使用组件时,可以充分利用类型检查和智能提示:

import { ref } from 'vue';

// 定义图片数据类型
type ImageUrl = string;

// 创建响应式数据
const imageUrl = ref<ImageUrl>('https://example.com/image.jpg');
const imageList = ref<ImageUrl[]>([
  'https://example.com/image1.jpg',
  'https://example.com/image2.jpg',
]);

// 事件处理函数
const handleImageLoad = (event: { width: number; height: number }) => {
  console.log(`图片加载成功,尺寸: ${event.width}x${event.height}`);
};

const handleImageError = (event: { err: Error }) => {
  console.error('图片加载失败:', event.err.message);
};

📋 API

TypeScript 类型定义

// 组件属性类型
interface LazyImageProps {
  src: string;           // 图片链接
  mode?: string;         // 图片裁剪、缩放的模式
  loading?: string;      // 加载中图片
  error?: string;        // 加载失败图片
  lazy?: boolean;        // 是否开启懒加载
  threshold?: number;    // 触发加载的阈值,单位为px
}

// 加载成功事件参数类型
interface LoadEventDetail {
  width: number;         // 图片宽度
  height: number;        // 图片高度
}

// 加载失败事件参数类型
interface ErrorEventDetail {
  err: Error;            // 错误对象
}

属性

属性名 类型 默认值 说明
src String - 图片链接
mode String 'aspectFill' 图片裁剪、缩放的模式
loading String - 加载中图片
error String - 加载失败图片
lazy Boolean true 是否开启懒加载
threshold Number 0 触发加载的阈值,单位为px

💡 性能提示:组件采用 Observer 观察模式,相比传统滚动监听方式性能提升显著,即使在大量图片的场景下也能保持流畅无卡顿。

事件

事件名 说明 回调参数
load 图片加载成功时触发 { width, height }
error 图片加载失败时触发 { err }

🌟 特性

  • ✅ 支持多种小程序平台
  • ✅ 轻量级,性能优秀
  • 采用 Observer 观察模式,性能极高,流畅无卡顿
  • ✅ 支持自定义加载中和加载失败图片
  • ✅ 可配置懒加载阈值
  • ✅ 完善的错误处理
  • ✅ 支持Vue3
  • ✅ 完整的 TypeScript 类型支持

📱 支持平台

平台 支持情况
微信小程序
支付宝小程序
百度小程序
字节跳动小程序
QQ小程序
H5
App-plus
5+App
Vue3
TypeScript

🤝 贡献

欢迎提交 Issue 和 Pull Request 来帮助改进这个组件。

📄 许可证

MIT License

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议