A Vue.js plugin for lazyload your Image or Component in your application.

Overview

Vue-Lazyload

Build Status npm version npm downloads npm license PRs Welcome CDNJS version

Vue module for lazyloading images in your applications. Some of goals of this project worth noting include:

  • Be lightweight, powerful and easy to use
  • Work on any image type
  • Add loading class while image is loading
  • Supports both of Vue 1.0 and Vue 2.0

Table of Contents

Demo

Demo

Requirements

Installation

npm

$ npm i vue-lazyload -S

yarn

$ yarn add vue-lazyload

CDN

CDN: https://unpkg.com/vue-lazyload/vue-lazyload.js

<script src="https://unpkg.com/vue-lazyload/vue-lazyload.js"></script>
<script>
  Vue.use(VueLazyload)
  ...
</script>

Usage

main.js:

import Vue from 'vue'
import App from './App.vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload)

// or with options
const loadimage = require('./assets/loading.gif')
const errorimage = require('./assets/error.gif')

Vue.use(VueLazyload, {
  preLoad: 1.3,
  error: errorimage,
  loading: loadimage,
  attempt: 1
})

new Vue({
  el: 'body',
  components: {
    App
  }
})

template:

<ul>
  <li v-for="img in list">
    <img v-lazy="img.src" >
  </li>
</ul>

use v-lazy-container work with raw HTML

<div v-lazy-container="{ selector: 'img' }">
  <img data-src="//domain.com/img1.jpg">
  <img data-src="//domain.com/img2.jpg">
  <img data-src="//domain.com/img3.jpg">  
</div>

custom error and loading placeholder image

<div v-lazy-container="{ selector: 'img', error: 'xxx.jpg', loading: 'xxx.jpg' }">
  <img data-src="//domain.com/img1.jpg">
  <img data-src="//domain.com/img2.jpg">
  <img data-src="//domain.com/img3.jpg">  
</div>
<div v-lazy-container="{ selector: 'img' }">
  <img data-src="//domain.com/img1.jpg" data-error="xxx.jpg">
  <img data-src="//domain.com/img2.jpg" data-loading="xxx.jpg">
  <img data-src="//domain.com/img3.jpg">  
</div>

Constructor Options

key description default options
preLoad proportion of pre-loading height 1.3 Number
error src of the image upon load fail 'data-src' String
loading src of the image while loading 'data-src' String
attempt attempts count 3 Number
listenEvents events that you want vue listen for ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove'] Desired Listen Events
adapter dynamically modify the attribute of element { } Element Adapter
filter the image's listener filter { } Image listener filter
lazyComponent lazyload component false Lazy Component
dispatchEvent trigger the dom event false Boolean
throttleWait throttle wait 200 Number
observer use IntersectionObserver false Boolean
observerOptions IntersectionObserver options { rootMargin: '0px', threshold: 0.1 } IntersectionObserver
silent do not print debug info true Boolean

Desired Listen Events

You can configure which events you want vue-lazyload by passing in an array of listener names.

Vue.use(VueLazyload, {
  preLoad: 1.3,
  error: 'dist/error.png',
  loading: 'dist/loading.gif',
  attempt: 1,
  // the default is ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend']
  listenEvents: [ 'scroll' ]
})

This is useful if you are having trouble with this plugin resetting itself to loading when you have certain animations and transitions taking place

Image listener filter

dynamically modify the src of image

Vue.use(vueLazy, {
    filter: {
      progressive (listener, options) {
          const isCDN = /qiniudn.com/
          if (isCDN.test(listener.src)) {
              listener.el.setAttribute('lazy-progressive', 'true')
              listener.loading = listener.src + '?imageView2/1/w/10/h/10'
          }
      },
      webp (listener, options) {
          if (!options.supportWebp) return
          const isCDN = /qiniudn.com/
          if (isCDN.test(listener.src)) {
              listener.src += '?imageView2/2/format/webp'
          }
      }
    }
})

Element Adapter

Vue.use(vueLazy, {
    adapter: {
        loaded ({ bindType, el, naturalHeight, naturalWidth, $parent, src, loading, error, Init }) {
            // do something here
            // example for call LoadedHandler
            LoadedHandler(el)
        },
        loading (listender, Init) {
            console.log('loading')
        },
        error (listender, Init) {
            console.log('error')
        }
    }
})

IntersectionObserver

use Intersection Observer to to improve performance of a large number of nodes.

Vue.use(vueLazy, {
  // set observer to true
  observer: true,

  // optional
  observerOptions: {
    rootMargin: '0px',
    threshold: 0.1
  }
})

Lazy Component

Vue.use(VueLazyload, {
  lazyComponent: true
});
<lazy-component @show="handler">
  <img class="mini-cover" :src="img.src" width="100%" height="400">
</lazy-component>

<script>
  {
    ...
    methods: {
      handler (component) {
        console.log('this component is showing')
      }
    }

  }
</script>

Use in list

<lazy-component v-for="(item, index) in list" :key="item.src" >
  <img class="mini-cover" :src="item.src" width="100%" height="400">
</lazy-component>

Implementation

Basic

vue-lazyload will set this img element's src with imgUrl string

<script>
export default {
  data () {
    return {
      imgObj: {
        src: 'http://xx.com/logo.png',
        error: 'http://xx.com/error.png',
        loading: 'http://xx.com/loading-spin.svg'
      },
      imgUrl: 'http://xx.com/logo.png' // String
    }
  }
}
</script>

<template>
  <div ref="container">
     <img v-lazy="imgUrl"/>
     <div v-lazy:background-image="imgUrl"></div>

     <!-- with customer error and loading -->
     <img v-lazy="imgObj"/>
     <div v-lazy:background-image="imgObj"></div>

     <!-- Customer scrollable element -->
     <img v-lazy.container ="imgUrl"/>
     <div v-lazy:background-image.container="img"></div>

    <!-- srcset -->
    <img v-lazy="'img.400px.jpg'" data-srcset="img.400px.jpg 400w, img.800px.jpg 800w, img.1200px.jpg 1200w">
    <img v-lazy="imgUrl" :data-srcset="imgUrl' + '?size=400 400w, ' + imgUrl + ' ?size=800 800w, ' + imgUrl +'/1200.jpg 1200w'" />
  </div>
</template>

CSS state

There are three states while img loading

loading loaded error

<img src="imgUrl" lazy="loading">
<img src="imgUrl" lazy="loaded">
<img src="imgUrl" lazy="error">
<style>
  img[lazy=loading] {
    /*your style here*/
  }
  img[lazy=error] {
    /*your style here*/
  }
  img[lazy=loaded] {
    /*your style here*/
  }
  /*
  or background-image
  */
  .yourclass[lazy=loading] {
    /*your style here*/
  }
  .yourclass[lazy=error] {
    /*your style here*/
  }
  .yourclass[lazy=loaded] {
    /*your style here*/
  }
</style>

Methods

Event Hook

vm.$Lazyload.$on(event, callback) vm.$Lazyload.$off(event, callback) vm.$Lazyload.$once(event, callback)

  • $on Listen for a custom events loading, loaded, error
  • $once Listen for a custom event, but only once. The listener will be removed once it triggers for the first time.
  • $off Remove event listener(s).

vm.$Lazyload.$on

Arguments:

  • {string} event
  • {Function} callback

Example

vm.$Lazyload.$on('loaded', function ({ bindType, el, naturalHeight, naturalWidth, $parent, src, loading, error }, formCache) {
  console.log(el, src)
})

vm.$Lazyload.$once

Arguments:

  • {string} event
  • {Function} callback

Example

vm.$Lazyload.$once('loaded', function ({ el, src }) {
  console.log(el, src)
})

vm.$Lazyload.$off

If only the event is provided, remove all listeners for that event

Arguments:

  • {string} event
  • {Function} callback

Example

function handler ({ el, src }, formCache) {
  console.log(el, src)
}
vm.$Lazyload.$on('loaded', handler)
vm.$Lazyload.$off('loaded', handler)
vm.$Lazyload.$off('loaded')

LazyLoadHandler

vm.$Lazyload.lazyLoadHandler

Manually trigger lazy loading position calculation

Example

this.$Lazyload.lazyLoadHandler()

Performance

this.$Lazyload.$on('loaded', function (listener) {
  console.table(this.$Lazyload.performance())
})

performance-demo

Dynamic switching pictures

 <img v-lazy="lazyImg" :key="lazyImg.src">

Authors && Contributors

License

The MIT License

Comments
  • Unable to get srcset to work as expected

    Unable to get srcset to work as expected

    Using version 1.2.2 with Vue 2.5.15

    I'm not able to get srcset to work as expected. The following output without your plugin works as expected in Chrome:

    <img
      srcset="http://via.placeholder.com/180x150 180w,http://via.placeholder.com/250x150 250w,http://via.placeholder.com/350x150 350w,http://via.placeholder.com/500x150 500w"
      sizes="(min-width: 1024px) 48.828125vw,(min-width: 768px) 45.57291666666667vw,100vw">
    

    When replacing srcset with data-srcset and adding v-lazy="'http://via.placeholder.com/180x150'" the 180x150 image is always shown. What do I oversee? Why is data-srcset not just converted to srcset when the image needs to be loaded and let the browser do the calculation (I know there would have to be a polyfill for older browsers)?

    opened by patric-eberle 30
  • 在移动端使用滑动的时候,我滑到的当前位置的图片不能显示,需要额外添加事件才能触发使得图片显示;在pc端需要只有滚轮滚到的地方才显示图片,手机模式拖动也是当前位置不显示图片……

    在移动端使用滑动的时候,我滑到的当前位置的图片不能显示,需要额外添加事件才能触发使得图片显示;在pc端需要只有滚轮滚到的地方才显示图片,手机模式拖动也是当前位置不显示图片……

    • ¥{{dish.price}}/份
      {{dish.quantity}}

      {{dish.title}}

    我需要额外添加click事件才能触发使得当前图片显示,而且我不清楚为什么每触发一次显示三张图
    opened by zhaozhaoduan 13
  • 关于filter一些问题

    关于filter一些问题

    1. filter文档中写someProcess,但是代码里写的是customer?

    2. webp其实也是customer,加了一层support detection.那么以后扩展会有webpa,webpb就显得比较奇怪了.所以我会选择直接都在customer写.

    3. 另外现在的customer是以el.attr存在的(或者说defaultFilter无需attr). 所以我尝试使用vue filter写过: v.lazy="item.image | toSize('120','120')"不起作用.是因为[email protected]不再支持这种写法了吗?

    opened by cjz9032 8
  • Feature:self defined the name of lazyload path

    Feature:self defined the name of lazyload path

    Q: Why I want to add this feature? A: Because in my project, i can' control the img tag, they come from the response data of my server api, and i can't know how many kinds.

    opened by JimChenWYU 7
  • supportWebp() will append a '!'

    supportWebp() will append a '!'

    function supportWebp () {
        if (!inBrowser) return false
    
        let support = true
        const d = document
    
        try {
            let el = d.createElement('object')
            el.type = 'image/webp'
            el.innerHTML = '!'
            d.body.appendChild(el)
            support = !el.offsetWidth
            d.body.removeChild(el)
        } catch (err) {
            support = false
        }
    
        return support
    }
    

    在没有使用 vue-ssr 的情况下,页面由 vue 进行前端渲染,会导致一开始白屏的时候,出现一个 ‘!’ 一闪而过

    bug 
    opened by BoltDoggy 7
  • Use for lazy-loading embedded videos?

    Use for lazy-loading embedded videos?

    I was trying to use this to lazy-load youtube videos embedded via their iframe widget, but unfortunately it doesn't work (it tries to convert the iframe source to data:image/png;base64).

    Can this be updated to also support lazy-loading of iframes?

    Example:

    <iframe width="560" height="315" frameborder="0"  v-lazy="'//www.youtube.com/embed/' + videoID" allowfullscreen></iframe>
    

    I would expect this video to be lazy-loaded, but using the current version it throws an error.

    opened by Cristy94 7
  • lazyload 展示第二屏的时候,并发请求图片非常慢

    lazyload 展示第二屏的时候,并发请求图片非常慢

    打开首屏还可以,但是滚动到第二屏的时候,图片并发请求,非常慢。去掉 lazyload 就正常了。网络情况相同,关掉 cache

    有 lazyload 的情况,会卡屏 http://7xs3k9.com1.z0.glb.clouddn.com/bug/with-vue-lazyload.MOV

    关掉 lazyload 的情况,非常顺畅 http://7xs3k9.com1.z0.glb.clouddn.com/bug/without-vue-lazyload.MOV

    wx20171219-160726 2x
    opened by itbdw 6
  • no versions available

    no versions available

    1.0.0rc12版本部分img标签上绑定loading和status状态失败,并没有初始化img的src默认值和状态,貌似绑定的$once事件也没有调用。。 0.9.x版本的global.install根本没有暴露VueLazyload对象,也没有绑定到window上,不能使用Vue.use(VueLazyload) 0.8.x版本的require不能直接在浏览器中使用

    opened by winkying 6
  • vue-lazy 如何结合富文本使用

    vue-lazy 如何结合富文本使用

    后台返回:<p><img src="http://a.object.gd-zht.com/2018/01/5a5f1a41ca358.jpg" style="max-width:100%;"><img src="http://a.object.gd-zhtcom/2018/01/5a5f1a452bd2c.jpg" style="font-size: 0.875rem; max-width: 100%;"><br></p> 正则替换img的src:

    <p><img v-lazy="http://a.object.gd-zht.com/2018/01/5a5f1a41ca358.jpg" style="max-width:100%;"><img v-lazy="http://a.object.gd-zht.com/2018/01/5a5f1a452bd2c.jpg" style="font-size: 0.875rem; max-width: 100%;"><br></p>

    用v-html渲染后: <p><img v-lazy="http://a.object.gd-zht.com/2018/01/5a5f1a41ca358.jpg" style="max-width:100%;"><img v-lazy="http://a.object.gd-zht.com/2018/01/5a5f1a452bd2c.jpg" style="font-size: 0.875rem; max-width: 100%;"><br></p> 还是这个,没有实现懒加载 ,请问这种情况怎么解决

    question 
    opened by ZooTopiaGG 5
  • horizontal scrolling not load?

    horizontal scrolling not load?

    I have a local area on the HTML page is a horizontal scrolling, when the picture elements from the outside of the screen scroll to the screen, the picture is not loaded, but then the vertical scroll, the picture will be loaded

    opened by aiyadingya 5
  • 在微信 WebView 中使用时 img 的背景先是会显示黑色

    在微信 WebView 中使用时 img 的背景先是会显示黑色

    滚动到未加载图片的 img 处,图片背景会显示为黑色,然后再加载图片。仅在微信的 WebView 中发现有这个问题,其余浏览器环境均正常。试过 !important 之类的方式设置 background-color,问题仍然存在。

    模板中的使用方式:

    <img v-lazy="photoUrl">
    
    opened by wangxiao 5
  • Is there a way to prevent console logging 404 error?

    Is there a way to prevent console logging 404 error?

    I've already tried this:

        app.use(VueLazyload, {
            preload: 1,
            error: LAZY_ERROR,
            loading: LAZY_LOADING,
            attempt: 3,
            dispatchEvent: true,
            adapter: {
                error(listener, Init) {
                    console.log(listener);
                },
            },
        });
    

    but in arguments of error adapter I found no way to stop it.

    and I also tried to add @error="errorHandler" to the <img> element. I can catch the event, but e.preventDefault() has no use:

    const errorHandler = (e: CustomEvent<any>) => {
        e.preventDefault();
        console.log(e)
    }
    // the type of 'e' is 'ReactiveListener'
    

    currently using vue 3.2.37, vue-lazyload 3.0.0-rc.2

    opened by summerset-zz 0
  • bug: lazy-compoent slots will lost its data binding, unless use ':key' to replace self.

    bug: lazy-compoent slots will lost its data binding, unless use ':key' to replace self.

    freeList.forEach(item => { remove(this.ListenerQueue, item) item.$destroy() }) there, if lazy component instance destroy self, will trigger its children slots destroy, and then lost data binding. Maybe we can remove listener instead of destroying it.

    opened by lihaochen 0
  • [Vue warn]: Failed to resolve directive: lazy (getting this error since last update)

    [Vue warn]: Failed to resolve directive: lazy (getting this error since last update)

    Suddenly vue-lazyload stopped working. I tried going back to the previous version but I still get the same error.

    [Vue warn]: Failed to resolve directive: lazy

    It was working yesterday so I suspect it has something to do with the latest update. However, manually choosing the previous version also did not help. Does someone know how to fix this?

    opened by fanopolis 2
Releases(v1.3.4)
Owner
Awe
get on, it's no time to explain
Awe
Awesome image component for vue2 & vue3 & nuxt. Lazyload / Responsive / Progressive / WebGL Filter / WebGL Transition / WebP

Awesome image component for vue2 & vue3 & nuxt. Lazyload / Responsive / Progressive / WebGL Filter / WebGL Transition / WebP

Phil Xu 54 Oct 2, 2022
Vue image lazyload directive

Vue image lazyload directive

alex koh 0 Nov 3, 2020
A lazyload plugin for Vue.js v2.x+.

vue-l-lazyload A lazyload and in-view detection plugin for Vue.js v2.x+. Demo Live demo or npm install vue-l-lazyload && npm run startDev to play it!

Light Leung 26 Mar 9, 2022
Vue Plugin for vanilla-lazyload

lazyload-vue Vue Plugin for vanilla-lazyload Build status: features Simple usage with v-lazy-src Accepts options Vue.use(LazyloadVue, options) Multipl

Kazap Tecnologia 29 Jul 14, 2022
Vue.js lazy load image directive with akamai image converter

vue-lazyload-akamai Vue.js lazy load image directive with akamai image converter ??

Blibli.com 2 Aug 13, 2018
Vue progressive image loading plugin

vue-progressive-image Vue progressive image loading plugin Installation $ npm install vue-progressive-image Usage import Vue from 'vue' import VueProg

Matteo Gabriele 708 Sep 30, 2022
Vue.js Image Kit Component with Lazy Load built in and Responsive Images

Vue Image Kit Vue.js Image Kit Component with Lazy Load built in and Responsive Images The inspiration comes from this and a talk from @derevandal in

Igor Guastalla 9 Mar 31, 2022
A Vue.js component to load an image automatically when it enters the viewport.

A Vue.js component to load an image automatically when it enters the viewport.

Ali Sarfaraz 0 Mar 29, 2020
simplistic vue.js directive for image lazy loading

Vue Progressive Image Lazy load images while showing a preview. Super tiny, less than half a kilobyte minified and gzipped. usage v-lazy-img adds the

Norman 25 Aug 11, 2021
:camera: Mini Image Lazy Loader for P(R)eact and Vue

Pimg is a Progessive Image Component For React, Preact and Vue.js. It helps in lazy loading of images in a nice and cool way. It's 2KB (gzipped). It h

Ademola. 98 Apr 24, 2021
A small lazy image loader for Vue

lazy-vue lazy-vue is the easiest way to get a lazy image loader working within your vue projects. It is meant to be as simplest as possible, so you do

Gustavo Ocanto 63 Jul 19, 2022
A super simple image lazy loader for Vue.

cube-vue-image-lazy A super simple image lazy loader for Vue. Install yarn add cube-vue-image-lazy Warning: You'll need to install the w3c Intersectio

Cube 4 Jun 19, 2020
Vue 2 image and video loader supporting lazy loading, background videos, fixed aspect ratios, low rez poster images, transitions, loaders, slotted content and more.

Vue Visual Vue 2 image and video loader supporting lazy loading. Visual 2.x is a simplification of Version 1.x with a greater reliance on modern brows

Bukwild 56 Sep 9, 2022
Create lazy image, embed, video and element with animation just with attributes.

?? Lazy-attr v1.2.3 Create lazy loading request or element like image, iframe, video... Make custom animation on lazy and not lazy element on all brow

null 1 Jan 4, 2022
A Lazy load plugin for Vue 3.x

vue3-lazy Status: Alpha. Lazy load plugin for Vue 3.x inspired by vue-lazyload. This plugin support very simple options, and easy to use. Install $ np

null 2 Feb 8, 2022
A plugin of lazy-load images for Vue2.x

vue-lazyload-images A plugin of lazy-load images for Vue2.x Support images lazyload in window or build-in element. Demo Installation npm $ npm install

LowesYang 60 Mar 28, 2022
Vue module for lazyloading images in your Vue 3 applications

Vue module for lazy-loading images in your vue 3 applications.

Jambon 22 Aug 19, 2022
The easiest way to lazy load your content

VueLazily The easiest way to lazy load your content. Inspired by vue-promised, recommend to look at it if you need loading/errors handling without laz

Enkot 6 Aug 31, 2022
Component-based lazy (CLazy) load images in Vue.js 2

Vue Clazy Load Claziest lazy loader out there! Component-based image lazy loader for Vue.js 2 Swaps between your image and another component when load

Matheus Grieger 108 Jun 14, 2022