v-photo
v1.0.0
Published
Vue.js plugin for img and picture HTML elements with support for browser-level lazy loading, and lazy loading using Intersection Observer API as fallback
Downloads
29
Maintainers
Readme
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
| Name | Type | Default | Description |
| ---------------------- | ------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| src
| String (*) | - | Image src
to lazy load when it intersects with the viewport |
| src-placeholder
| String | ' ' | If defined, it will be shown until the src
image is loaded. |
| alt
| String | ' ' | img alt attribute |
| intersection-options
| Object | () => ({}) | The Intersection Observer options object. |
| use-picture
| Boolean | false | Wrap the img in a picture tag. |
| use-lazy
| Boolean | true | Turn off lazy loading |
Events
| Name | Description |
| ----------- | -------------------------------------------------------- |
| intersect
| Triggered when the image intersects the viewport |
| load
| Triggered when the image defined in src
is loaded |
| error
| Triggered when the image defined in src
fails to load |