0
# Directive Usage
1
2
Vue directives for declarative lazy loading of images and background images in templates.
3
4
## Capabilities
5
6
### v-lazy Directive
7
8
Main directive for lazy loading images and background images with automatic viewport detection.
9
10
```typescript { .api }
11
/**
12
* v-lazy directive for lazy loading images
13
* Supports both img src and background-image loading
14
*/
15
interface LazyDirective {
16
/** Initialize lazy loading when element is mounted */
17
beforeMount(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
18
/** Handle updates to lazy loading configuration */
19
beforeUpdate(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
20
/** Trigger lazy load check after updates */
21
updated(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
22
/** Clean up lazy loading when element is unmounted */
23
unmounted(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
24
}
25
26
/**
27
* Value types accepted by v-lazy directive
28
*/
29
type LazyDirectiveValue = string | VueLazyloadImageOptions;
30
31
interface VueLazyloadImageOptions {
32
/** Image source URL */
33
src: string;
34
/** Error fallback image URL */
35
error?: string;
36
/** Loading placeholder image URL */
37
loading?: string;
38
/** Maximum loading attempts */
39
attempt?: number;
40
}
41
```
42
43
**Usage Examples:**
44
45
```vue
46
<template>
47
<!-- Basic image lazy loading -->
48
<img v-lazy="imageUrl" alt="Lazy loaded image">
49
50
<!-- Background image lazy loading -->
51
<div v-lazy:background-image="backgroundUrl" class="hero-section"></div>
52
53
<!-- Custom container scrolling -->
54
<div ref="scrollContainer" class="custom-scroll">
55
<img v-lazy.container="imageUrl" alt="Image in custom container">
56
</div>
57
58
<!-- Object configuration with custom placeholders -->
59
<img v-lazy="{
60
src: '/high-res-image.jpg',
61
loading: '/loading-spinner.gif',
62
error: '/error-placeholder.png',
63
attempt: 5
64
}" alt="High resolution image">
65
66
<!-- Srcset support -->
67
<img
68
v-lazy="'/image-400.jpg'"
69
data-srcset="/image-400.jpg 400w, /image-800.jpg 800w, /image-1200.jpg 1200w"
70
sizes="(max-width: 400px) 400px, (max-width: 800px) 800px, 1200px"
71
alt="Responsive image">
72
</template>
73
74
<script setup>
75
import { ref } from "vue";
76
77
const imageUrl = ref("/path/to/image.jpg");
78
const backgroundUrl = ref("/path/to/background.jpg");
79
</script>
80
```
81
82
### v-lazy-container Directive
83
84
Directive for lazy loading multiple images within a container element.
85
86
```typescript { .api }
87
/**
88
* v-lazy-container directive for batch lazy loading
89
* Automatically finds and lazy loads images within a container
90
*/
91
interface LazyContainerDirective {
92
/** Initialize container lazy loading */
93
beforeMount(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
94
/** Update container configuration */
95
updated(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
96
/** Clean up container lazy loading */
97
unmounted(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
98
}
99
100
/**
101
* Configuration for v-lazy-container directive
102
*/
103
interface LazyContainerOptions {
104
/** CSS selector for images to lazy load (default: 'img') */
105
selector?: string;
106
/** Default error image for all images in container */
107
error?: string;
108
/** Default loading image for all images in container */
109
loading?: string;
110
}
111
```
112
113
**Usage Examples:**
114
115
```vue
116
<template>
117
<!-- Basic container lazy loading -->
118
<div v-lazy-container="{ selector: 'img' }">
119
<img data-src="/image1.jpg" alt="Image 1">
120
<img data-src="/image2.jpg" alt="Image 2">
121
<img data-src="/image3.jpg" alt="Image 3">
122
</div>
123
124
<!-- Container with custom error and loading images -->
125
<div v-lazy-container="{
126
selector: 'img',
127
error: '/error.png',
128
loading: '/loading.gif'
129
}">
130
<img data-src="/photo1.jpg" alt="Photo 1">
131
<img data-src="/photo2.jpg" alt="Photo 2">
132
</div>
133
134
<!-- Individual image overrides -->
135
<div v-lazy-container="{ selector: 'img' }">
136
<img data-src="/image1.jpg" data-error="/custom-error.png" alt="Image 1">
137
<img data-src="/image2.jpg" data-loading="/custom-loading.gif" alt="Image 2">
138
<img data-src="/image3.jpg" alt="Image 3">
139
</div>
140
141
<!-- Custom selector for different elements -->
142
<div v-lazy-container="{ selector: '.lazy-bg' }">
143
<div class="lazy-bg" data-src="/bg1.jpg">Content 1</div>
144
<div class="lazy-bg" data-src="/bg2.jpg">Content 2</div>
145
</div>
146
</template>
147
```
148
149
### Directive Modifiers
150
151
Modifiers available for fine-tuning directive behavior.
152
153
```typescript { .api }
154
/**
155
* Supported modifiers for v-lazy directive
156
*/
157
interface LazyDirectiveModifiers {
158
/** Use custom scrollable container instead of window */
159
[containerRef: string]: boolean;
160
}
161
```
162
163
**Usage Examples:**
164
165
```vue
166
<template>
167
<div ref="customContainer" class="scrollable-area">
168
<!-- Image will use customContainer as scroll parent -->
169
<img v-lazy.customContainer="imageUrl" alt="Image in custom container">
170
</div>
171
172
<!-- Multiple images with same container -->
173
<div ref="gallery" class="image-gallery">
174
<img v-lazy.gallery="image1" alt="Gallery Image 1">
175
<img v-lazy.gallery="image2" alt="Gallery Image 2">
176
<img v-lazy.gallery="image3" alt="Gallery Image 3">
177
</div>
178
</template>
179
180
<script setup>
181
import { ref } from "vue";
182
183
const customContainer = ref();
184
const gallery = ref();
185
const imageUrl = ref("/image.jpg");
186
const image1 = ref("/gallery1.jpg");
187
const image2 = ref("/gallery2.jpg");
188
const image3 = ref("/gallery3.jpg");
189
</script>
190
```
191
192
### CSS State Classes
193
194
CSS classes automatically added to elements to indicate loading state.
195
196
```typescript { .api }
197
/**
198
* CSS lazy attribute values added to elements
199
*/
200
type LazyState = "loading" | "loaded" | "error";
201
```
202
203
**Usage Examples:**
204
205
```vue
206
<template>
207
<img v-lazy="imageUrl" alt="Lazy image" class="lazy-image">
208
</template>
209
210
<style>
211
/* Style based on loading state */
212
.lazy-image[lazy="loading"] {
213
opacity: 0.5;
214
background: url('/loading-spinner.gif') center no-repeat;
215
}
216
217
.lazy-image[lazy="loaded"] {
218
opacity: 1;
219
transition: opacity 0.3s ease;
220
}
221
222
.lazy-image[lazy="error"] {
223
opacity: 0.8;
224
background: url('/error-icon.png') center no-repeat;
225
}
226
227
/* Background image states */
228
.hero-section[lazy="loading"] {
229
background-image: url('/loading-pattern.png');
230
}
231
232
.hero-section[lazy="loaded"] {
233
transition: background-image 0.5s ease;
234
}
235
236
.hero-section[lazy="error"] {
237
background-image: url('/fallback-bg.jpg');
238
}
239
</style>
240
```
241
242
### Advanced Directive Usage
243
244
Complex scenarios and integration patterns.
245
246
**Dynamic Image Sources:**
247
248
```vue
249
<template>
250
<!-- Reactive image source -->
251
<img v-lazy="computedImageUrl" alt="Dynamic image">
252
253
<!-- Conditional lazy loading -->
254
<img v-if="shouldLazyLoad" v-lazy="imageUrl" alt="Conditional lazy image">
255
<img v-else :src="imageUrl" alt="Direct load image">
256
</template>
257
258
<script setup>
259
import { computed, ref } from "vue";
260
261
const baseUrl = ref("/images/");
262
const imageName = ref("photo.jpg");
263
const devicePixelRatio = ref(window.devicePixelRatio || 1);
264
265
const computedImageUrl = computed(() => {
266
const suffix = devicePixelRatio.value > 1 ? "@2x" : "";
267
return `${baseUrl.value}${imageName.value}${suffix}`;
268
});
269
270
const shouldLazyLoad = computed(() => {
271
// Only lazy load on mobile or slow connections
272
return window.innerWidth < 768 || navigator.connection?.effectiveType === "slow-2g";
273
});
274
</script>
275
```
276
277
**Integration with Vue Transitions:**
278
279
```vue
280
<template>
281
<transition name="fade" appear>
282
<img v-lazy="imageUrl" @load="onImageLoad" alt="Transitioning image">
283
</transition>
284
</template>
285
286
<script setup>
287
const onImageLoad = () => {
288
console.log("Image loaded and transition completed");
289
};
290
</script>
291
292
<style>
293
.fade-enter-active, .fade-leave-active {
294
transition: opacity 0.5s;
295
}
296
.fade-enter-from, .fade-leave-to {
297
opacity: 0;
298
}
299
</style>
300
```