1.0.0 • Published 4 years ago

v-photo v1.0.0

Weekly downloads
8
License
SEE LICENSE IN LI...
Repository
github
Last release
4 years ago

v-photo

A Vue.js component to lazy load an image automatically when it enters the viewport using lazy Loading at the Browser-Level or as fallback Intersection Observer API.

Plugin is inspired by v-lazy-image.

Lazy Loading at the Browser-Level

v-photo is detects support for browser-level lazy loading and uses it as default. If browser-level lazy loading is not supported by browser fallback is Intersection Observer.

More information on: https://web.dev/native-lazy-loading/

Usage

npm install v-photo

Warning: You'll need to install the w3c Intersection Observer polyfill in case you're targeting a browser which doesn't support it.

You can register the component globally so it's available in all your apps:

import Vue from "vue";
import vPhoto from 'v-photo';

Vue.use(vPhoto);

Or use it locally in any of your components:

import vPhoto from "v-photo";

export default {
  components: {
    vPhoto
  }
};

You must pass an src property with the link of the image:

<template>
  <v-photo src="http://lorempixel.com/400/200/" />
</template>

That image will be loaded as soon as the image enters the viewport.

Progressive Loading

You can use the src-placeholder property to define an image that is shown until the src image is loaded.

When the src image is loaded, a is-loaded class is added, so you can use it to perform animations. For example, a blur effect:

<template>
  <v-photo
    src="http://lorempixel.com/400/200/"
    src-placeholder="http://lorempixel.com/200/200/"
  />
</template>

<style scoped>
.v-photo {
  filter: blur(10px);
  transition: filter 0.7s;
}
.v-photo.is-loaded {
  filter: blur(0);
}
</style>

In case you are using Webpack bundler for images too (just like Vue-cli):

<v-photo
  src="http://lorempixel.com/400/200/"
  :src-placeholder="require('../assets/img.jpg')"
/>

You could listen to the intersect and load events for more complex animations and state handling:

<template>
  <v-photo
    src="http://lorempixel.com/400/200/"
    src-placeholder="http://lorempixel.com/200/200/"
    @intersect="..."
    @load="..."
  />
</template>

@jmperezperez has written about the progressive loading technique on his blog, in case you want a deeper explanation.

Picture

If you want to wrap the img in a picture tag, use the prop usePicture. You can then use slots to add additional elements above the img element`.

<v-photo
  src="http://lorempixel.com/400/200/"
  alt="Fallback"
  use-picture
>
  <source srcset="http://lorempixel.com/1680/1024/" media="(min-width: 1024px)" />
</v-photo>

Renders as:

<picture>
  <source srcset="http://lorempixel.com/1680/1024/" media="(min-width: 1024px)" />
  <img srcset="http://lorempixel.com/400/200/" alt="Fallback" />
</picture>

Note you can use the picture polyfill.

API

Fields marked as (*) are required.

Props

NameTypeDefaultDescription
srcString (*)-Image src to lazy load when it intersects with the viewport
src-placeholderString' 'If defined, it will be shown until the src image is loaded.
altString' 'img alt attribute
intersection-optionsObject() => ({})The Intersection Observer options object.
use-pictureBooleanfalseWrap the img in a picture tag.
use-lazyBooleantrueTurn off lazy loading

Events

NameDescription
intersectTriggered when the image intersects the viewport
loadTriggered when the image defined in src is loaded
errorTriggered when the image defined in src fails to load