CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue-lazyload

Vue.js plugin for lazy-loading images and components with directives, components, and programmatic APIs

Pending
Overview
Eval results
Files

directives.mddocs/

Directive Usage

Vue directives for declarative lazy loading of images and background images in templates.

Capabilities

v-lazy Directive

Main directive for lazy loading images and background images with automatic viewport detection.

/**
 * v-lazy directive for lazy loading images
 * Supports both img src and background-image loading
 */
interface LazyDirective {
  /** Initialize lazy loading when element is mounted */
  beforeMount(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
  /** Handle updates to lazy loading configuration */
  beforeUpdate(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
  /** Trigger lazy load check after updates */
  updated(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
  /** Clean up lazy loading when element is unmounted */
  unmounted(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
}

/**
 * Value types accepted by v-lazy directive
 */
type LazyDirectiveValue = string | VueLazyloadImageOptions;

interface VueLazyloadImageOptions {
  /** Image source URL */
  src: string;
  /** Error fallback image URL */
  error?: string;
  /** Loading placeholder image URL */
  loading?: string;
  /** Maximum loading attempts */
  attempt?: number;
}

Usage Examples:

<template>
  <!-- Basic image lazy loading -->
  <img v-lazy="imageUrl" alt="Lazy loaded image">
  
  <!-- Background image lazy loading -->
  <div v-lazy:background-image="backgroundUrl" class="hero-section"></div>
  
  <!-- Custom container scrolling -->
  <div ref="scrollContainer" class="custom-scroll">
    <img v-lazy.container="imageUrl" alt="Image in custom container">
  </div>
  
  <!-- Object configuration with custom placeholders -->
  <img v-lazy="{
    src: '/high-res-image.jpg',
    loading: '/loading-spinner.gif',
    error: '/error-placeholder.png',
    attempt: 5
  }" alt="High resolution image">
  
  <!-- Srcset support -->
  <img 
    v-lazy="'/image-400.jpg'"
    data-srcset="/image-400.jpg 400w, /image-800.jpg 800w, /image-1200.jpg 1200w"
    sizes="(max-width: 400px) 400px, (max-width: 800px) 800px, 1200px"
    alt="Responsive image">
</template>

<script setup>
import { ref } from "vue";

const imageUrl = ref("/path/to/image.jpg");
const backgroundUrl = ref("/path/to/background.jpg");
</script>

v-lazy-container Directive

Directive for lazy loading multiple images within a container element.

/**
 * v-lazy-container directive for batch lazy loading
 * Automatically finds and lazy loads images within a container
 */
interface LazyContainerDirective {
  /** Initialize container lazy loading */
  beforeMount(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
  /** Update container configuration */
  updated(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
  /** Clean up container lazy loading */
  unmounted(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void;
}

/**
 * Configuration for v-lazy-container directive
 */
interface LazyContainerOptions {
  /** CSS selector for images to lazy load (default: 'img') */
  selector?: string;
  /** Default error image for all images in container */
  error?: string;
  /** Default loading image for all images in container */
  loading?: string;
}

Usage Examples:

<template>
  <!-- Basic container lazy loading -->
  <div v-lazy-container="{ selector: 'img' }">
    <img data-src="/image1.jpg" alt="Image 1">
    <img data-src="/image2.jpg" alt="Image 2">
    <img data-src="/image3.jpg" alt="Image 3">
  </div>
  
  <!-- Container with custom error and loading images -->
  <div v-lazy-container="{
    selector: 'img',
    error: '/error.png',
    loading: '/loading.gif'
  }">
    <img data-src="/photo1.jpg" alt="Photo 1">
    <img data-src="/photo2.jpg" alt="Photo 2">
  </div>
  
  <!-- Individual image overrides -->
  <div v-lazy-container="{ selector: 'img' }">
    <img data-src="/image1.jpg" data-error="/custom-error.png" alt="Image 1">
    <img data-src="/image2.jpg" data-loading="/custom-loading.gif" alt="Image 2">
    <img data-src="/image3.jpg" alt="Image 3">
  </div>
  
  <!-- Custom selector for different elements -->
  <div v-lazy-container="{ selector: '.lazy-bg' }">
    <div class="lazy-bg" data-src="/bg1.jpg">Content 1</div>
    <div class="lazy-bg" data-src="/bg2.jpg">Content 2</div>
  </div>
</template>

Directive Modifiers

Modifiers available for fine-tuning directive behavior.

/**
 * Supported modifiers for v-lazy directive
 */
interface LazyDirectiveModifiers {
  /** Use custom scrollable container instead of window */
  [containerRef: string]: boolean;
}

Usage Examples:

<template>
  <div ref="customContainer" class="scrollable-area">
    <!-- Image will use customContainer as scroll parent -->
    <img v-lazy.customContainer="imageUrl" alt="Image in custom container">
  </div>
  
  <!-- Multiple images with same container -->
  <div ref="gallery" class="image-gallery">
    <img v-lazy.gallery="image1" alt="Gallery Image 1">
    <img v-lazy.gallery="image2" alt="Gallery Image 2">
    <img v-lazy.gallery="image3" alt="Gallery Image 3">
  </div>
</template>

<script setup>
import { ref } from "vue";

const customContainer = ref();
const gallery = ref();
const imageUrl = ref("/image.jpg");
const image1 = ref("/gallery1.jpg");
const image2 = ref("/gallery2.jpg");
const image3 = ref("/gallery3.jpg");
</script>

CSS State Classes

CSS classes automatically added to elements to indicate loading state.

/**
 * CSS lazy attribute values added to elements
 */
type LazyState = "loading" | "loaded" | "error";

Usage Examples:

<template>
  <img v-lazy="imageUrl" alt="Lazy image" class="lazy-image">
</template>

<style>
/* Style based on loading state */
.lazy-image[lazy="loading"] {
  opacity: 0.5;
  background: url('/loading-spinner.gif') center no-repeat;
}

.lazy-image[lazy="loaded"] {
  opacity: 1;
  transition: opacity 0.3s ease;
}

.lazy-image[lazy="error"] {
  opacity: 0.8;
  background: url('/error-icon.png') center no-repeat;
}

/* Background image states */
.hero-section[lazy="loading"] {
  background-image: url('/loading-pattern.png');
}

.hero-section[lazy="loaded"] {
  transition: background-image 0.5s ease;
}

.hero-section[lazy="error"] {
  background-image: url('/fallback-bg.jpg');
}
</style>

Advanced Directive Usage

Complex scenarios and integration patterns.

Dynamic Image Sources:

<template>
  <!-- Reactive image source -->
  <img v-lazy="computedImageUrl" alt="Dynamic image">
  
  <!-- Conditional lazy loading -->
  <img v-if="shouldLazyLoad" v-lazy="imageUrl" alt="Conditional lazy image">
  <img v-else :src="imageUrl" alt="Direct load image">
</template>

<script setup>
import { computed, ref } from "vue";

const baseUrl = ref("/images/");
const imageName = ref("photo.jpg");
const devicePixelRatio = ref(window.devicePixelRatio || 1);

const computedImageUrl = computed(() => {
  const suffix = devicePixelRatio.value > 1 ? "@2x" : "";
  return `${baseUrl.value}${imageName.value}${suffix}`;
});

const shouldLazyLoad = computed(() => {
  // Only lazy load on mobile or slow connections
  return window.innerWidth < 768 || navigator.connection?.effectiveType === "slow-2g";
});
</script>

Integration with Vue Transitions:

<template>
  <transition name="fade" appear>
    <img v-lazy="imageUrl" @load="onImageLoad" alt="Transitioning image">
  </transition>
</template>

<script setup>
const onImageLoad = () => {
  console.log("Image loaded and transition completed");
};
</script>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
</style>

Install with Tessl CLI

npx tessl i tessl/npm-vue-lazyload

docs

components.md

directives.md

index.md

plugin-installation.md

programmatic-api.md

tile.json