vue-lazyload-imgs
v1.0.2
Published
This Vue component vue-lazyload-imgs is used to implement lazy loading of images in Vue2 (Vue>=2.6.0) and Vue3 framework environments. The difference from some lazy loading image instructions is that this component can lazily load any number of images at
Maintainers
Readme
🚀 vue-lazyload-imgs(LazyLoadImgs) 组件简介
适用环境:本组件适用于运行在前端开发框架 Vue,同时兼容 Vue2(>=2.6.0)及 Vue3 版本;要求 Vue 版本必须在 2.6.0(包含) 以上及 Vue 3.x.x 版本,即 "vue": ">=2.6.0 || ^3.0.0";
功能简介:vue-lazyload-imgs 本组件用于实现在 >=2.6.0 及 3.x.x 的 Vue 版本中实现图片的懒加载功能。将包裹在本组件内的所有 html 深层次结构内的图片标签 <img> 实现懒加载功能,初始进入页面及随着页面滚动,只有进入页面窗口可视范围内的图片才会加载显示,从而提升页面的加载速度和用户体验;
组件特性:本组件(图片懒加载组件)具有如下特性:
本组件可一性实现懒加载任意数量的图片,而不是像某些图片懒加载指令那样,每个<img>图片标签都要添加 v- 开头的自定义图片懒加载指令;本组件只需要将要加载的任意数量的<img>图片标签包裹起来(即把要加载的所有图片及其父标签作为本组件 LazyLoadImgs 的默认插槽内容),<img>图片标签可以嵌套任意层次,并且<img>图片标签可以在任何其它合法的 html 标签内,具体可查看【使用方法】部分)。
本组件还支持实现懒加载由 v-html 指令梆定的 html 字符串内容里面的<img>图片,这些场景特别适用于一些带有图片的文章或留言内容,在 Vue3 中,使用本组件渲染 v-html 指令梆定的 html 内容时,必须与本组件标签内的 v-model 指令搭配使用,否则本组件包裹内(即默认插槽内)的使用了 v-html 指令梆定的 html 内容里的 <img> 图片不能实现懒加载,这是由于 Vue3 对使用 v-html 指令渲染 html 内容的虚拟节点渲染原理所需; 在 Vue2 环境下,使用本组件渲染 v-html 指令梆定的 html内容时,可以不在本组件标签内设置 v-model 指令和 htmlFieldName 参数也可以,不过为了使用本组件时,与 Vue3 代码保持一致,及方便迁移到 Vue3 环境,建议 Vue2 环境下也加入 v-model 指令和 htmlFieldName 参数; 详细请查看【Props 参数说明】部分,示例代码如下:
// 如下 v-for 循环的 key 参数请保证使用唯一值(也可安装使用 nanoid 包生成唯一值),不建议采用数组索引 index
// keyFieldName 参数:要渲染的每个对象中的包含 html 内容的字段/属性名,
// 如果 v-model 指令值不是像本例的包含要渲染的 html 内容的对象数组,而是一项简单的 html 字符串,则不需要设置 keyFieldName 参数
<template>
<LazyLoadImgs v-model="articleList">
<div
v-for="{artId, content} in articleList"
:key="artId"
v-html="content"
keyFieldName="content"
>
</div>
</LazyLoadImgs>
<!-- 【注】:如果本组件标签内的 v-model 指令值不是如上的对象数组,而是 html 字符串(即只需要渲染一项 html 内容),则直接把在块标签如 div 标签内的 v-html 指令值设置为和在本组件标签内的 v-model 指令值一样的响应式 html 字符串变量即可,也不用再设置 htmlFieldName 参数,如下:
-->
<LazyLoadImgs v-model="oneArticle">
<div v-html="oneArticle"></div>
</LazyLoadImgs>
</template>
<script setup>
import { ref } from 'vue';
// 由本组件的 v-model 指令梆定的包含要渲染 html 内容字段的对象数组列表,
// 要求数组中的每个对象至少要包含表示唯一ID和要渲染的 html 字符串的两个属性
const articleList = ref([
{
artId: 1, // 唯一ID(必须)
author: 'Samdy_Chan'
title: '文章1标题',
content: '<p>这是文章1内容 <img src="https://www.baidu.com/img/flexible/logo/pc/result.png" /></p>', // 要渲染的 html 字符串(必须)
createTime: '2025-01-01 12:30:01'
},
{
artId: 2,
author: 'Andy_Lau'
title: '文章2标题',
content: '<p>这是文章2内容 <img src="https://www.baidu.com/img/flexible/logo/pc/result.png" /></p>',
createTime: '2025-01-03 21:45:32'
}
]);
// 渲染模板中,第二个<LazyLoadImgs>组件的 v-model 指令梆定的只渲染一项 html 内容
const oneArticle = `
<div>
<p>这是只渲染一篇文章内容</p>
<img src="https://www.baidu.com/img/flexible/logo/pc/result.png" />
</div>
`;
</script>
// 【注】:本组件只支持懒加载标准 html 标签内的<img>图片,不支持将其它组件(假定如下的 <MyImgList> 组件封装了很多<img>图片标签,则将 <MyImgList> 组件放在本组件 <LazyLoadImgs> 默认插槽内,是不能实现懒加载 <MyImgList> 组件内的图片的,这是 Vue 的虚拟节点渲染结构导致。
// 【如下是不能实现懒加载效果的】:
<template>
<LazyLoadImgs>
<!-- 不能实现懒加载 MyImgList 组件内的图片, 本组件 LazyLoadImgs 只能包裹标准的 html 标签。
请在 MyImgList 组件中,使用本 LazyLoadImgs 组件包裹要懒加载的<img>图片标签即可。
-->
<MyImgList />
</LazyLoadImgs>
</template>🚀 安装方法
## npm
npm install vue-lazyload-imgs
## yarn
yarn add vue-lazyload-imgs
## pnpm
pnpm add vue-lazyload-imgs🚀 使用方法
- 在 html 标签如 div 里使用 v-html 指令渲染 html 内容及实现懒加载 html 内容里的 <img> 图片,请查看以上【本组件简介->组件特性】第二部分。 v-html 指令需要与本组件内的 v-model 指令以及 Props 参数 htmlFieldName 一起使用。
方法一:全局使用
(a)、全局注册 For Vue2(Vue >=2.6.x,并且 <=2.7.x):
// main.ts or main.js
import Vue from 'vue';
import App from './App.vue';
// 为 Vue2.6.x 导入 @vue/composition-api 插件(Vue2.7.x 自动集成,无须执行此行)
import VueCompositionApi from '@vue/composition-api'; // Only for Vue2.6.x
// 使用默认导入方式导入本组件
import LazyLoadImgs from 'vue-lazyload-imgs';
// 为 Vue2.6.x 注册 @vue/composition-api 插件(Vue2.7.x 自动集成,无须执行此行)
Vue.use(VueCompositionApi); // Only for Vue2.6.x
// 【可选】:可配置在以下使用 Vue.use 全局注册本组件时,传入该 lazyOptions 对象配置参数,
// 作为像局部使用本组件时,传递的 Props 参数。
// 这样,在各页面及组件文件中使用本组件时,可不用再传递 Props 参数,这里配置的 lazyOptions 参数是用户为本组件定义的默认参数。
/*
const lazyOptions = {
loadingImg: 'https://img.soogif.comB84eqI5yyJKNYiKJyvqL9SXtgKTmqi1k.gif_jpg',
errorImg: 'https://www.91ajs.com/content-data/upload/202303/202303071603195893.png',
delay: 3000,
lifeFunc: {
loading: (img: HTMLImageElement) => {
console.log('图片加载中', img);
},
loaded: (img: HTMLImageElement) => {
console.log('加载图片成功,图片地址是:', img.src, img);
},
error: (img: HTMLImageElement) => {
console.log('加载图片失败,图片地址是:', img.src, img);
},
},
};
*/
// 全局注册本组件:缺省不传该 lazyOptions 参数,本组件也提供了内置的 Props 参数,
// 详见【Props & Events/参数和事件说明】部分。
Vue.use(LazyLoadImgs /*, lazyOptions */);
new Vue({
render: h => h(App)
}).$mount('#app');(b)、全局注册 For Vue3(Vue >=3.x.x):
// main.ts or main.js
import { createApp } from 'vue';
import App from './App.vue';
// 使用默认导入方式导入本组件
import LazyLoadImgs from 'vue-lazyload-imgs';
const app = createApp(App);
// 【可选】:可配置在以下使用 app.use 全局注册本组件时,传入该 lazyOptions 对象配置参数,
// 作为像局部使用本组件时,传递的 Props 参数。
// 这样,在各页面及组件文件中使用本组件时,可不用再传递 Props 参数,这里配置的 lazyOptions 参数是用户为本组件定义的默认参数。
/*
const lazyOptions = {
loadingImg: 'https://img.soogif.comB84eqI5yyJKNYiKJyvqL9SXtgKTmqi1k.gif_jpg',
errorImg: 'https://www.91ajs.com/content-data/upload/202303/202303071603195893.png',
delay: 3000,
lifeFunc: {
loading: (img: HTMLImageElement) => {
console.log('图片加载中', img);
},
loaded: (img: HTMLImageElement) => {
console.log('加载图片成功,图片地址是:', img.src, img);
},
error: (img: HTMLImageElement) => {
console.log('加载图片失败,图片地址是:', img.src, img);
},
},
};
*/
// 全局注册本组件:缺省不传该 lazyOptions 参数,本组件也提供了内置的 Props 参数,
// 详见【Props 参数说明】部分。
app.use(LazyLoadImgs /*, lazyOptions */);
app.mount('#app');<!-- App.vue -->
<!-- 以上全局注册本组件后,在其它任何页面及组件中(如App.vue) 中无须导入,即可以直接使用本组件 -->
<template>
<!-- 1、采用默认 Props 参数使用本组件(默认参数值详见以下的【Props 参数说明】部分) -->
<LazyLoadImgs>
<div class="container">
<img src="https://tb2.bdstatic.com/tb/static-common/img/search_logo_big_v2_d84d082.png" />
<section class="aside">
<div class="aside-left">
<img src="https://www.baidu.com/img/flexible/logo/pc/result.png" />
</div>
</section>
</div>
</LazyLoadImgs>
<!-- 2、指定自定义 Props 参数使用本组件(可传递的参数和事件回调及说明详见以下的【Props 参数说明】部分),
Props 使用驼峰或中横线分隔均可,如 :lazy-options 同 :lazyOptions -->
<LazyLoadImgs :lazy-options="lazyOptions" :observer-options="observerOptions">
<img src="https://tb2.bdstatic.com/tb/static-common/img/search_logo_big_v2_d84d082.png" />
</LazyLoadImgs>
</template>
<script setup>
import { ref } from 'vue';
// 配置本懒加载组件 LazyLoadImgs 的 Props 参数
const lazyOptions = ref({
loadingImg: 'https://img.soogif.comB84eqI5yyJKNYiKJyvqL9SXtgKTmqi1k.gif_jpg',
errorImg: 'https://www.91ajs.com/content-data/upload/202303/202303071603195893.png',
delay: 3000,
lifeFunc: {
loading: (img: HTMLImageElement) => {
console.log('图片加载中', img);
},
loaded: (img: HTMLImageElement) => {
console.log('加载图片成功,图片地址是:', img.src, img);
},
error: (img: HTMLImageElement) => {
console.log('加载图片失败,图片地址是:', img.src, img);
},
},
});
// 图片进入可视区监听器参数配置:建议缺省(不用指定)该参数,采用默认值即可
const observerOptions = {
// 图片进入可视交叉状态的根容器,默认为浏览器视口(null),建议取默认值 null 即可
root: null,
// 根容器 margin 值,建议取默认值 0px 即可
rootMargin: '0px',
// 图片进入与根容器交叠重叠范围的百分比(0-1之间),即进入可视范围多少百分比后,进行加载,建议取默认值为 0 即可(刚进入可视边界即加载)
threshold: 0
};
</script>方法二:局部(组件内)使用
// 如在 App.vue 或其它组件中使用本组件
// 需使用分别导入方式导入本组件(因为全局注册使用了默认导入方式)
import { LazyLoadImgs } from 'vue-lazyload-imgs';
// 本组件在 <template></template> 模板标签中使用的方式和传递参数和如上的【全局使用】方法相同。🚀 Props 参数说明
以下所有参数均具有默认值,均为可选参数,绝大多数情况下,本组件不用指定以下任何参数,即可实现图片懒加载功能。
🚀 CHANGELOG(版本变更记录)
v1.0.0 : 完成了实现图片懒加载功能的开发与测试,包括懒加载模板中 html 标签内的 <img> 标签的图片,及懒加载 Vue 内置的 v-html 指令值梆定的 html 字符串内的 <img> 标签的图片。
v1.0.1 : 优化代码,删除多余的代码;修改 package.json 中的对等依赖配置。
v1.0.2 : 优化代码,添加了一些 ts 类型声明,删除一些测试文件及多余的 ts 文件。
