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

Vue实现一个图片懒加载插件(转载)的更多相关文章

  1. [jQuery插件]手写一个图片懒加载实现

    教你做图片懒加载插件 那一年 那一年,我还年轻 刚接手一个ASP.NET MVC 的 web 项目, (C#/jQuery/Bootstrap) 并没有做 web 的经验,没有预留学习时间, (作为项 ...

  2. Vue图片懒加载插件

    图片懒加载是一个很常用的功能,特别是一些电商平台,这对性能优化至关重要.今天就用vue来实现一个图片懒加载的插件. 这篇博客采用"三步走"战略--Vue.use().Vue.dir ...

  3. jQuery图片懒加载插件jquery.lazyload.js使用实例注意事项说明

    jQuery图片懒加载插件jquery.lazyload.js使用实例注意事项说明 jquery.lazyload.js是一个用JavaScript编写的jQuery插件.它可以延迟加载长页面中的图片 ...

  4. 图片懒加载插件lazyload使用方法

    图片懒加载插件lazyload使用方法 一.如何使用: Lazy Load 依赖于 jQuery.引入文件 <script type="text/javascript" sr ...

  5. JS实现图片懒加载插件

    一.前言 我在前几篇博客的记录中,有说自己在做一个图片懒加载的功能,然后巴拉巴拉的遇到哪些问题,结果做完了也没对懒加载这个功能做一些记录,所以这篇文章主要针对我所实现的思路,以及代码做个记录,实现不佳 ...

  6. 原生js开发,无依赖、轻量级的现代浏览器图片懒加载插件,适合在移动端开发使用

    优势 1.原生js开发,不依赖任何框架或库 2.支持将各种宽高不一致的图片,自动剪切成默认图片的宽高 比如说你的默认图片是一张正方形的图片,则各种宽度高度不一样的图片,自动剪切成正方形. 完美解决移动 ...

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

    1.安装 npm i vue-lazyload -S 2.配置 main.js /***图片模板等懒加载 start ***/ import VueLazyload from 'vue-lazyloa ...

  8. Js 之图片懒加载插件

    一.PC端(lazyload) 1.引入js文件 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.m ...

  9. 图片懒加载插件echo.js——改造

    今天做一个列表项需要用到懒加载,搜到网友推荐的echo.js,试用了一下,还不错.除了懒加载,还提供了throttle——节流,即用户快速滑动列表时,很快滑过的项的图片不会加载,只会加载最后停下来的位 ...

随机推荐

  1. Beta冲刺(1/4)

    队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:学习了很多东西 Github签入记录 接下来的计划:继续学习 还剩下哪些任务:后端部分 燃尽图 遇到的困难:自己太菜了 收获和疑问: ...

  2. mysql order by rand() 优化方法

    mysql order by rand() 优化方法 适用于领取奖品等项目<pre>mysql> select * from user order by rand() limit 1 ...

  3. Google BERT

    概述 BERT的全称是Bidirectional Encoder Representation from Transformers,即双向Transformer的Encoder,因为decoder是不 ...

  4. gitlab 重置密码

    sudo gitlab-rails console production --------------------------------------------------------------- ...

  5. Ubuntu 18.04 LTS 设置代理(系统代理;http 代理;sock5 代理;apt 代理 ...)

    1. 设置系统代理 1.1 设置 http 代理 1.1.1 只在当前 shell 生效 export http_proxy="http://<user>:<passwor ...

  6. FZU2018级算法第五次作业 m_sort(归并排序或线段树求逆序对)

    首先对某人在未经冰少允许情况下登录冰少账号原模原样复制其代码并且直接提交的赤裸裸剽窃行为,并且最终被评为优秀作业提出抗议! 题目大意: 给一个数组含n个数(1<=n<=5e5),求使用冒泡 ...

  7. 剑指offer22:从上往下打印出二叉树的每个节点,同层节点从左至右打印。

    1 题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 2 思路和方法 使用一个队列存放节点.先将根节点加入到队列中,然后循环遍历队列中的元素,遍历过程中,访问该节点的左右子节点,再将左 ...

  8. 使用keepalived实现kubenetes apiserver高可用

    # 安装 nginx yum install nginx -y # 配置nginx4层代理 /etc/nginx/nginx.conf stream { upstream kube-apiserver ...

  9. ALV报表——选择屏幕变量赋值

    ABAP选择屏幕变量赋值 运行效果: 代码: *&---------------------------------------------------------------------* ...

  10. shell 学习笔记7-shell-函数

    一.函数 1.什么是shell函数 把相同程序段定义成函数,可以减少整个程序的代码量,提升开发效率 增加程序的可读性,易读性,提升管理效率 可以失效程序功能模块化,使程序具备可移植性 其实linux系 ...