Appearance
lazy 图片懒加载指令
用于懒加载图片或背景图,在元素进入视口时再设置 src/srcset 或 background-image,支持回调与一次性加载。
安装与引入
按需导入(推荐)
ts
import { VLazy } from '@cuixingjian/cui-utils'全局注册
ts
import { createApp } from 'vue'
import { VLazy } from '@cuixingjian/cui-utils'
const app = createApp(App)
app.directive('lazy', VLazy)
app.mount('#app')局部注册
vue
<script setup lang="ts">
import { VLazy as vLazy } from '@cuixingjian/cui-utils'
</script>
<template>
<img v-lazy data-src="image.jpg" />
</template>效果演示
基础用法
滚动页面查看图片懒加载效果。
使用代码
使用 data-src 属性:
vue
<template>
<img
src="placeholder.png"
data-src="https://example.com/real.jpg"
v-lazy
/>
</template>使用配置对象:
vue
<template>
<img v-lazy="{ src: 'https://example.com/image.jpg' }" />
</template>懒加载背景图:
vue
<template>
<div
v-lazy="{ bg: 'https://example.com/bg.jpg' }"
style="min-height: 200px; background-size: cover;"
>
内容
</div>
</template>带回调:
vue
<script setup lang="ts">
function onLoad(el: Element) {
console.log('图片加载完成', el)
}
</script>
<template>
<img v-lazy="{ src: 'image.jpg', onLoad }" />
</template>API 说明
指令值类型
| 类型 | 说明 | 示例 |
|---|---|---|
string | 直接传入图片地址 | v-lazy="'image.jpg'" |
Object | 传入配置对象 | v-lazy="{ src: 'image.jpg' }" |
配置选项 (LazyDirectiveOptions)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| src | string | — | 图片真实地址(不传则读取 data-src) |
| srcset | string | — | 图片 srcset(不传则读取 data-srcset) |
| bg | string | — | 背景图地址(不传则读取 data-bg) |
| root | Element | null | null | IntersectionObserver 的根元素 |
| rootMargin | string | '0px' | 视口边距,如 '200px 0px' |
| threshold | number | number[] | 0 | 触发阈值(0-1) |
| once | boolean | true | 是否仅加载一次 |
| srcAttr | string | 'data-src' | 自定义读取的属性名 |
| srcsetAttr | string | 'data-srcset' | 自定义读取的属性名 |
| bgAttr | string | 'data-bg' | 自定义读取的属性名 |
| beforeLoad | (el: Element) => void | — | 加载前回调 |
| onLoad | (el: Element) => void | — | 加载成功回调 |
| onError | (el: Element, error: any) => void | — | 加载失败回调 |
注意事项
IntersectionObserver
- 使用 IntersectionObserver API 实现懒加载
- 不支持的环境会直接加载图片
- 可通过
threshold控制触发时机
占位处理
建议在真实资源加载前设置占位:
- 使用占位图片
- 添加骨架屏
- 使用模糊效果(blur)
- 设置背景色
性能优化
once: true避免重复加载- 使用
rootMargin提前加载 - 合理设置
threshold值
常见场景
- 图片列表:大量图片懒加载
- 长页面:分屏加载内容
- 背景图:懒加载背景图片
- 响应式图片:使用 srcset
源码展示
展开查看完整源码
ts
import type { Directive } from 'vue'
import { withInstallDirective } from '../install'
export interface LazyDirectiveOptions {
root?: Element | null
rootMargin?: string
threshold?: number | number[]
src?: string
srcset?: string
bg?: string
srcAttr?: string
srcsetAttr?: string
bgAttr?: string
beforeLoad?: (el: Element) => void
onLoad?: (el: Element) => void
onError?: (el: Element, error: any) => void
once?: boolean
}
// 详见 packages/utils/directives/lazy.ts
export const VLazy = withInstallDirective(lazy, 'lazy')