vue-lazyload使用总结(推荐)


Posted in Javascript onNovember 01, 2018

当你用vue开发的时候,不可避免的就会遇到图片懒加载的问题,之前jquery时代有jquery.lazyload.js,但是那个肯定不能用在vue的项目里。查阅资料后发现Vue-Lazyload这个插件用的频率还是比较高,最近刚好也在研究vue的懒加载,顺便也仔细研究了以下这个插件,这个插件确实能够实现懒加载,但是坑也有不少,今天就一起来看看Vue-Lazyload。 Vue-Lazyload的github地址

主要功能&实现思路

这篇文章不是去讲解这个插件是如何配置的,这个在它的github上都有介绍,因此你要先大致了解它是如何配置的。这里主要从源码角度去分析该如何正确使用这款插件。

v-lazy

这个是Vue-Lazyload最常用的一个东西,用法也非常的简单:

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

我们现在来看看它的内部是如何实现的,首先我们进入它github上的源码可以发现它的定义:

Vue.directive('lazy', {
  bind: lazy.add.bind(lazy),
  update: lazy.update.bind(lazy),
  componentUpdated: lazy.lazyLoadHandler.bind(lazy),
  unbind: lazy.remove.bind(lazy)
})
Vue.directive('lazy-container', {
  bind: lazyContainer.bind.bind(lazyContainer),
  update: lazyContainer.update.bind(lazyContainer),
  unbind: lazyContainer.unbind.bind(lazyContainer)
})

我们可以发现它是利用vue的自定义指令实现的,vue的自定义指令可以自定义v-***之类的指令,例如你定义了Vue.directive('demo',..)那么你就可以使用v-demo这样的指令,当你使用了之后就会有对应事件供你回调,例如bind,insert,unbind等,具体可以看看下面的demo:

=> vue自定义指令(二维码)

进入demo后我们可以看到一进去就出发了bind和insert事件,然后你在输入框输入内容就会触发update和updateComponent事件,当你点击隐藏就会触发unbind事件,当你点击显示则又会触发bind和insert事件。(具体含义可以去查阅官方文档)

vue的自定义指令还可以带参数,例如vue-lazy:background-image.container='src'这样的结构,我们可以通过事件里面的binding参数获取到,例如上面的background-image可以通过binding.arg获取,.container可以通过binding.modifiers获取。

好了,讲了这么多,v-lazy的实现思路应该比较清楚了,就是内部实现了一个lazy的类,通过vue自定义指令将对象和参数传进去,然后通过检测事件(scroll等)检测位置,如果一旦这个对象出现在屏幕里就加载图片。下面看看已经实现好的demo:(包含img的v-lazy和div的v-lazy:background-image两种情况)

=> v-lazy demo(二维码)

注意:这里的v-lazy='src'中的src一定要使用data里面的变量,不能写真实的图片路径,这样会报错导致没有效果,因为vue的自定义指令必须对应data中的变量或者是数字,你写一个图片路径识别不了,我之前就是被坑了。(这里的图片fadeIn效果是在load事件之后添加了一个fadeIn的class)。

v-lazy-container

这个总体上和v-lazy差不多,也是通过自定义指令去定义的,不过v-lazy-container扫描的是内部的子元素,v-lazy-container一般使用如下:

<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>

v-lazy-container和v-lazy不同的是,v-lazy-container是通过设置指定的子元素的data-src,data-loading,data-error去设置图片的路径的,我们看内部实现就可以看到:

const imgs = this.getImgs()
imgs.forEach(el => {
   this.lazy.add(el, assign({}, this.binding, {
     value: {
       src: 'dataset' in el ? el.dataset.src : el.getAttribute('data-src'),
       error: 'dataset' in el ? el.dataset.error : el.getAttribute('data-error'),
       loading: 'dataset' in el ? el.dataset.loading : el.getAttribute('data-loading')
     }
   }), this.vnode)
 })

下面是写好的v-lazy-container demo:

=> v-lazy-container demo(二维码)

注:v-lazy-container内部指定元素设置的data-src是图片的真实路径,不能是data变量,这个和v-lazy完全相反。

lazy-component

这个和上面的不太一样,这个严格来说不单单能够做图片懒加载,还可以做组件的懒加载,一般结构如下:

<lazy-component @show="handler">
   <img class="mini-cover" :src="img.src" width="100%" height="400">
</lazy-component>

实现方面,先用Vue.component('lazy-component',...)注册了一个全局的组件,然后通过检测位置,如果在视图范围之内就吐出它内部的内容,这个设计还是比较巧妙:

render (h) {
   if (this.show === false) {
     return h(this.tag)
   }
   return h(this.tag, null, this.$slots.default)
 },

我们一般用component都是指定一个template,它这里是利用render来自己生成内容,它这里通过一个变量show控制是否绘制内部的内容,开始的时候show为false,那么这里就绘制一个div(tag为div),等检测(检测div)出现屏幕了,show就为true,就会绘制它内部的真实内容了(this.$slots.default就是自定义控件下面的内容)。

lazy-component作为一个组件,给外部提供了一个回调事件(show),表示已经开始load了,所以我们可以在外层监听这个事件:

load () {
   this.show = true
   this.state.loaded = true
   this.$emit('show', this)
 }

我们来看一个做好的demo,这个demo还是以实现图片懒加载为主。

=> lazy-component demo(二维码)

注:lazy-component本身不能实现图片懒加载,它只是实现组件懒加载,上面demo真正实现懒加载是因为用了v-lazy。lazy-component有一个问题,就是它的上方必须要有东西,否则可能没有效果,因为它在检测的时候有一个判断:bottom>0,所以如果你在第一个元素使用lazy-component可能没有效果。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
IE浏览器PNG图片透明效果代码
Sep 02 Javascript
Jquery css函数用法(判断标签是否拥有某属性)
May 28 Javascript
jquery应该如何来设置改变按钮input的onclick事件
Dec 10 Javascript
容易造成JavaScript内存泄露几个方面
Sep 04 Javascript
jquery实现鼠标滑过小图时显示大图的方法
Jan 14 Javascript
javascript中Date对象的使用总结
Nov 21 Javascript
开源免费天气预报接口API及全国所有地区代码(国家气象局提供)
Dec 26 Javascript
微信小程序 两种滑动方式(横向滑动,竖向滑动)详细及实例代码
Jan 13 Javascript
vue的常用组件操作方法应用分析
Apr 13 Javascript
js实现多个倒计时并行 js拼团倒计时
Feb 25 Javascript
vue实现图片上传预览功能
Dec 23 Javascript
Vue js with语句原理及用法解析
Sep 03 Javascript
vue 中基于html5 drag drap的拖放效果案例分析
Nov 01 #Javascript
Vue列表渲染的示例代码
Nov 01 #Javascript
socket io与vue-cli的结合使用的示例代码
Nov 01 #Javascript
Vue表单输入绑定的示例代码
Nov 01 #Javascript
浅谈Angular 观察者模式理解
Nov 01 #Javascript
详解vuex状态管理模式
Nov 01 #Javascript
详解angularjs跨页面传参遇到的一些问题
Nov 01 #Javascript
You might like
咖啡的种类和口感
2021/03/03 新手入门
ThinkPHP实现非标准名称数据表快速创建模型的方法
2014/11/29 PHP
UPUPW 更新 64 位 Apache 系列 PHP 7.0 正式版
2015/12/08 PHP
php简单复制文件的方法
2016/05/09 PHP
PHP文字转图片功能原理与实现方法分析
2017/08/31 PHP
PHP实现单条sql执行多个数据的insert语句方法
2019/10/11 PHP
JavaScript 组件之旅(三):用 Ant 构建组件
2009/10/28 Javascript
json的前台操作和后台操作实现代码
2012/01/20 Javascript
JavaScript的Module模式编程深入分析
2013/08/13 Javascript
页面加载完后自动执行一个方法的js代码
2014/09/06 Javascript
jQuery中delegate()方法用法实例
2015/01/19 Javascript
js实现拖拽效果
2015/02/12 Javascript
javascript简单实现类似QQ头像弹出效果的方法
2015/08/03 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
2016/03/17 Javascript
js获取元素的标签名实现方法
2016/10/08 Javascript
js将字符串中的每一个单词的首字母变为大写其余均为小写
2017/01/05 Javascript
使用canvas及js简单生成验证码方法
2017/04/02 Javascript
深入浅析Node.js单线程模型
2017/07/10 Javascript
详解vue2.0模拟后台json数据
2019/05/16 Javascript
在Vue中使用icon 字体图标的方法
2019/06/14 Javascript
JS实现提示框跟随鼠标移动
2019/08/27 Javascript
Vue数字输入框组件示例代码详解
2020/01/15 Javascript
JavaScript如何判断对象有某属性
2020/07/03 Javascript
[01:21:07]EG vs Liquid 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
[01:25:38]DOTA2-DPC中国联赛 正赛 VG vs LBZS BO3 第一场 1月19日
2021/03/11 DOTA
python装饰器的特性原理详解
2019/12/25 Python
python__new__内置静态方法使用解析
2020/01/07 Python
sklearn的predict_proba使用说明
2020/06/28 Python
python自动化测试三部曲之request+django实现接口测试
2020/10/07 Python
CSS3系列教程:背景图片(背景大小和多背景图) 应用说明
2012/12/19 HTML / CSS
FLOS美国官网:意大利高级照明工艺的传奇
2018/08/07 全球购物
如何在C# winform中异步调用web services
2015/09/21 面试题
实习鉴定范文
2013/12/19 职场文书
开办饭店创业计划书
2013/12/28 职场文书
2016秋季运动会前导词
2015/11/25 职场文书
不同品牌、不同型号对讲机如何互相通联
2022/02/18 无线电