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 相关文章推荐
我也种棵OO树JXTree[js+css+xml]
Apr 02 Javascript
JQuery onload、ready概念介绍及使用方法
Apr 27 Javascript
JQuery AJAX 中文乱码问题解决
Jun 05 Javascript
JavaScript中的eval()函数使用介绍
Dec 31 Javascript
jQuery实现表格展开与折叠的方法
May 04 Javascript
让浏览器崩溃的12行JS代码(DoS攻击分析及防御)
Oct 10 Javascript
深入理解Angularjs中的$resource服务
Dec 31 Javascript
bootstrap laydate日期组件使用详解
Jan 04 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)
Jan 21 Javascript
Webpack4 使用Babel处理ES6语法的方法示例
Mar 07 Javascript
Vue图片浏览组件v-viewer用法分析【支持旋转、缩放、翻转等操作】
Nov 04 Javascript
vue编写简单的购物车功能
Jan 08 Vue.js
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
PHP的FTP学习(二)
2006/10/09 PHP
我的论坛源代码(三)
2006/10/09 PHP
php利用curl抓取新浪微博内容示例
2014/04/27 PHP
对于ThinkPHP框架早期版本的一个SQL注入漏洞详细分析
2014/07/04 PHP
php去除html标记的原生函数详解
2015/01/27 PHP
php递归函数三种实现方法及如何实现数字累加
2015/08/07 PHP
PHP信号量基本用法实例详解
2016/02/12 PHP
php文件上传及下载附带显示文件及目录功能
2017/04/27 PHP
javascript firefox不显示本地预览图片问题的解决方法
2008/11/12 Javascript
禁止你的左键复制实用技巧
2013/01/04 Javascript
浅析IE10兼容性问题(frameset的cols属性)
2014/01/03 Javascript
jquery实现通用版鼠标经过淡入淡出效果
2014/06/15 Javascript
网页运行时提示对象不支持abigimage属性或方法
2014/08/10 Javascript
javascript实现table表格隔行变色的方法
2015/05/13 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
2015/12/16 Javascript
javascript瀑布流布局实现方法详解
2016/02/17 Javascript
JS控制TreeView的结点选择
2016/11/11 Javascript
bootstrap fileinput 插件使用项目总结(经验)
2017/02/22 Javascript
JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】
2017/09/28 Javascript
vue项目中使用Svg的方法
2018/10/24 Javascript
JS基于对象的链表实现与使用方法示例
2019/01/31 Javascript
nodejs实现聊天机器人功能
2019/09/19 NodeJs
Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享
2016/07/04 Python
获取python的list中含有重复值的index方法
2018/06/27 Python
Window系统下Python如何安装OpenCV库
2020/03/05 Python
Python利用myqr库创建自己的二维码
2020/11/24 Python
python3实现名片管理系统(控制台版)
2020/11/29 Python
英国最大的网上药品商店:Chemist Direct
2017/12/16 全球购物
Jack Rogers官网:美国经典的女性鞋靴品牌
2019/09/04 全球购物
政府领导干部个人对照检查材料思想汇报
2014/09/24 职场文书
小学德育工作总结2015
2015/05/12 职场文书
劳动仲裁调解书
2015/05/20 职场文书
2015年幼儿园教育教学工作总结
2015/05/25 职场文书
追悼会答谢词范文
2015/09/29 职场文书
详解Oracle数据库中自带的所有表结构(sql代码)
2021/11/20 Oracle
Win10 最新稳定版本 21H2开始推送
2022/04/19 数码科技