Vue 自定义图片懒加载指令v-lazyload

  Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍。以下将详细介绍如何实现自定义指令v-lazyload。

  先看如何使用这个指令:

  

<img v-lazyload="imageSrc" >

  imageSrc是要加载的图片的实际路径。

  为了实现这个指令,我们首先单独建立一个文件,名字为lazyload.js.并填写基本的代码,如下:

  

//Vue 图片懒加载,导出模块
export default (Vue , options = {})=>{  //初始化的选项,default是未加载图片时显示的默认图片
    var init = {
      default: ‘https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png‘
    }  //addListener为Vue指令的具体实现功能函数,我们这里为所有使用v-lazyload的指令的元素添加监听  //ele 是dom元素,binding是绑定的具体值,  //例如:<img v-lazyload="imageSrc" > ele是img binding是imageSrc
  const addListenner = (ele,binding) =>{      }  //Vue自定义指令,lazyload为指令的名称
    Vue.directive(‘lazyload‘,{
        inserted:addListener,
        updated:addListener
    })
}

inserted 和 updated为Vue指令的执行不同阶段提供的钩子函数,查看Vue的官网可以看到一共有5个阶段,

指令定义函数提供了几个钩子函数(可选):

  • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
  • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
  • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
  • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
  • unbind: 只调用一次, 指令与元素解绑时调用。

这里我们只用inserted和updated就够了。

  接下来我们具体实现addListener的实现。我们的具体思路如下:

  1、先看看这个图片是否需要懒加载。有两种情况,一是图片还没到达可视区域,二是图片已经加载过了。

  2、然后监听窗口的scroll事件,判断哪些图片可以进行懒加载了。

  这里我们需要一个需要进行监听需要懒加载的图片列表和一个需要记录已经加载过得图片列表。另外为了方便数组的操作,我们加一个数组的remove方法。

  继续我们的代码。

//Vue 图片懒加载
export default (Vue , options = {})=>{    //数组item remove方法
  if(!Array.prototype.remove){
        Array.prototype.remove = function(item){
            if(!this.length) return
            var index = this.indexOf(item);
            if( index > -1){
                this.splice(index,1);
                return this
            }
        }
    }
  var init = {       default: ‘https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png‘   }    //需要进行监听的图片列表,还没有加载过得   var listenList = [];  //已经加载过得图片缓存列表
    var imageCatcheList = [];
  //是否已经加载过了
    const isAlredyLoad = (imageSrc) => {

    }
    //检测图片是否可以加载,如果可以则进行加载
    const isCanShow = (item) =>{

    };
  //添加监听事件scroll
    const onListenScroll = () =>{

    }
    //Vue 指令最终的方法
    const addListener = (ele,binding) =>{
        //绑定的图片地址
        var imageSrc = binding.value;
        //如果已经加载过,则无需重新加载,直接将src赋值
        if(isAlredyLoad(imageSrc)){
            ele.src = imageSrc;
            return false;
        }
        var item = {
            ele:ele,
            src:imageSrc
        }
        //图片显示默认的图片
        ele.src = init.default;
        //再看看是否可以显示此图片
        if(isCanShow(item)){
            return
        }
        //否则将图片地址和元素均放入监听的lisenList里
        listenList.push(item);

        //然后开始监听页面scroll事件
        onListenScroll();
    }

    Vue.directive(‘lazyload‘,{
        inserted:addListener,
        updated:addListener
    })
}

接下来就几个空方法的实现了。

isAlredyLoad ,判断是否已经加载过了这个图片
const isAlredyLoad = (imageSrc) => {
        if(imageCatcheList.indexOf(imageSrc) > -1){
            return true;
        }else{
            return false;
        }
    }

isCanShow 图片是否进入可视区域,如果已经进入则进行加载

//检测图片是否可以加载,如果可以则进行加载
    const isCanShow = (item) =>{
        var ele = item.ele;
        var src = item.src;
        //图片距离页面顶部的距离
        var top = ele.getBoundingClientRect().top;
        //页面可视区域的高度
        var windowHeight = window.innerHight;
        //top + 10 已经进入了可视区域10像素
        if(top + 10 < window.innerHeight){
            var image = new Image();
            image.src = src;
            image.onload = function(){
                ele.src = src;
                imageCatcheList.push(src);
                listenList.remove(item);
            }
            return true;
        }else{
            return false;
        }
    };
onListenScroll监听滚动事件,并且检测是否进入可视区域。
const onListenScroll = () =>{
        window.addEventListener(‘scroll‘,function(){
            var length = listenList.length;
            for(let i = 0;i<length;i++ ){
                isCanShow(listenList[i]);
            }
        })
    }

最终我们的代码如下:

//Vue 图片懒加载
export default (Vue , options = {})=>{
    if(!Array.prototype.remove){
        Array.prototype.remove = function(item){
            if(!this.length) return
            var index = this.indexOf(item);
            if( index > -1){
                this.splice(index,1);
                return this
            }
        }
    }
    var init = {
        lazyLoad: false,
      default: ‘https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png‘
    }

    var listenList = [];
    var imageCatcheList = [];

    const isAlredyLoad = (imageSrc) => {
        if(imageCatcheList.indexOf(imageSrc) > -1){
            return true;
        }else{
            return false;
        }
    }
    //检测图片是否可以加载,如果可以则进行加载
    const isCanShow = (item) =>{
        var ele = item.ele;
        var src = item.src;
        //图片距离页面顶部的距离
        var top = ele.getBoundingClientRect().top;
        //页面可视区域的高度
        var windowHeight = window.innerHight;
        //top + 10 已经进入了可视区域10像素
        if(top + 10 < window.innerHeight){
            var image = new Image();
            image.src = src;
            image.onload = function(){
                ele.src = src;
                imageCatcheList.push(src);
                listenList.remove(item);
            }
            return true;
        }else{
            return false;
        }
    };

    const onListenScroll = () =>{
        window.addEventListener(‘scroll‘,function(){
            var length = listenList.length;
            for(let i = 0;i<length;i++ ){
                isCanShow(listenList[i]);
            }
        })
    }
    //Vue 指令最终的方法
    const addListener = (ele,binding) =>{
        //绑定的图片地址
        var imageSrc = binding.value;
        //如果已经加载过,则无需重新加载,直接将src赋值
        if(isAlredyLoad(imageSrc)){
            ele.src = imageSrc;
            return false;
        }
        var item = {
            ele:ele,
            src:imageSrc
        }
        //图片显示默认的图片
        ele.src = init.default;
        //再看看是否可以显示此图片
        if(isCanShow(item)){
            return
        }
        //否则将图片地址和元素均放入监听的lisenList里
        listenList.push(item);

        //然后开始监听页面scroll事件
        onListenScroll();
    }

    Vue.directive(‘lazyload‘,{
        inserted:addListener,
        updated:addListener
    })
}

使用时需要在主文件中引入这个文件,并且vue.use();

import LazyLoad from ‘lazyLoad.js‘Vue.use(LazyLoad);

并且在需要懒加载的图片上均按照如下使用v-lazyload指令即可

<img v-lazyload="imageSrc" >
时间: 2024-10-01 14:59:18

Vue 自定义图片懒加载指令v-lazyload的相关文章

Vue实现一个图片懒加载插件

前言 图片懒加载是一个很常用的功能,特别是一些电商平台,这对性能优化至关重要.今天就用vue来实现一个图片懒加载的插件. 这篇博客采用"三步走"战略--Vue.use().Vue.direction.Vue图片懒加载插件实现,逐步实现一个Vue的图片懒加载插件. Vue.use() 就像开发jQuery插件要用$.fn.extent()一样,开发Vue插件我们要用Vue.use().其实就是官方内部实现的一个方法,供广大开发者灵活开发属于自己的插件.只需要按照约定好的规则开发就行. 用

vue 图片懒加载

//Vue 图片懒加载export default (Vue , options = {})=>{ if(!Array.prototype.remove){ Array.prototype.remove = function(item){ if(!this.length) return var index = this.indexOf(item); if( index > -1){ this.splice(index,1); return this } } } var init = { laz

vue + vue-lazyload 实现图片懒加载

1.安装 npm i vue-lazyload -S 2.配置 main.js /***图片模板等懒加载 start ***/ import VueLazyload from 'vue-lazyload' // 404图片 import errImg from './assets/img/404.png' // loading图片 import loadingImg from './assets/img/loading-spin.svg' // 图片懒加载配置 Vue.use(VueLazylo

Vue图片懒加载

图片懒加载的原理 先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src).当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果.这样做能防止页面一次性向服务器响应大量请求导致服务器响应慢,页面卡顿或崩溃等问题. 实现步骤: 1.安装插件: npm install vue-lazyload --save-dev 2. main.js引入插件: import VueLazyLoad

vue 图片懒加载 vue-lazyload

在项目中,如果出现大图一时半会加载不出来 的情况确实很丑.如果是那种没有给定宽高 靠图片撑起来的等图片加载出来 再把内容挤下去的用户体验效果非常差. 在vue中 使用vue-lazyload可以实现图片懒加载 安装 npm install vue-lazyload --save 引用 main.js import vueLazy from 'vue-lazyload' Vue.use(vueLazy) index.vue <template> <div> <img v-laz

vue项目中实现图片懒加载的方法

对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载.这样子对于页面加载性能上会有很大的提升,也提高了用户体验. 实现方法(使用vue的vue-lazyload插件) 1.安装插件 npm install vue-lazyload --save-dev 2.在入口文件main.js中引入并使用 import VueLazyload from 'vue-lazyload' 直接使用 Vue.use(VueLazyl

【vue】vue-cli3构建项目中实现图片懒加载

前两天正好写了文章如何用实现图片懒加载[性能优化]JS实现图片懒加载,今天在使用vue构建项目的时候就遇到了要做图片懒加载的优化需要,本想把前两天的代码直接copy过来的,后来想查查看有没有更简便的方法,果不其然,vue中直接有插件可以使用,看了下实现时候的效果,实现原理都和原生js是一样的,vue果然真香! 接下来我们来讲vue-lazyload插件的使用: 1.安装插件 cnpm i vue-lazyload -S 2.入口文件main.js中配置: import Vue from 'vue

js效果笔记:怎样实现图片的懒加载以及jquery.lazyload.js的使用

在项目中有时候会用到图片的延迟加载,那么延迟加载的好处是啥呢? 我觉得主要包括两点吧,第一是在包含很多大图片长页面中延迟加载图片可以加快页面加载速度:第二是帮助降低服务器负担. 下面介绍一下常用的延迟加载插件jquery.lazyload.js以及怎样实现一个延迟加载的插件. 一:jquery.lazyload.js插件 lazyload是jQuery写的延迟加载插件,在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动到它们所在的位置. 这与图片预加载的处理方式正好是相反的. 实现原理 首

实现图片懒加载

Web 图片的懒加载就是通过读取img元素,然后获得img元素的data-src(也可以约定为其他属性名)属性的值,并赋予img的src,从而实现动态加载图片的机制. 这里需要注意的是: img在初始化的时候不要设置src属性,因为即使设置 src='' 浏览器也会尝试加载图片. 一个简单的图片懒加载共涉及两个方面, 1. HTML 约定 我们首先需要给准备实施懒加载的img元素添加指定的class 这里为m-lazyload ,同时将img src赋值给 data-src属性.具体示例为: <