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

网友投稿 539 2022-10-26


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

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

先看如何使用这个指令:

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

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

export  (Vue , options = {})=> init =: '和 updated为Vue指令的执行不同阶段提供的钩子函数,查看Vue的官网可以看到一共有5个阶段,

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

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

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

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

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

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

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

继续我们的代码。

export  (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             }         }     }

init =: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png' listenList = p_w_picpathCatcheList == (p_w_picpathSrc) =>     const isCanShow = (item) =>= () =>     const addListener = (ele,binding) =>          p_w_picpathSrc =         =  item =         ele.src = init.         'lazyload'

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

isAlredyLoad ,判断是否已经加载过了这个图片

const isAlredyLoad = (p_w_picpathSrc) => {        if(p_w_picpathCatcheList.indexOf(p_w_picpathSrc) > -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 p_w_picpath = new Image();             p_w_picpath.src = src;             p_w_picpath.onload = function(){                 ele.src = src;                 p_w_picpathCatcheList.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

最终我们的代码如下:

//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 p_w_picpathCatcheList = [];     const isAlredyLoad = (p_w_picpathSrc) => {        if(p_w_picpathCatcheList.indexOf(p_w_picpathSrc) > -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 p_w_picpath = new Image();             p_w_picpath.src = src;             p_w_picpath.onload = function(){                 ele.src = src;                 p_w_picpathCatcheList.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{        //绑定的图片地址         var p_w_picpathSrc = binding.value;        //如果已经加载过,则无需重新加载,直接将src赋值         if(isAlredyLoad(p_w_picpathSrc)){             ele.src = p_w_picpathSrc;            return false;         }        var item = {             ele:ele,             src:p_w_picpathSrc         }        //图片显示默认的图片         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指令即可


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Web层框架对网站中所有异常的统一处理
下一篇:Spring框架学习之AOP详解
相关文章

 发表评论

评论列表