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 自定义图片懒加载指令v-lazyload的更多相关文章

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

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

  2. 【vue】---- 图片懒加载

    1.作用 在图片较多的页面中,页面加载性能较差.使用图片懒加载可以让图片出现在可视区域时再进行加载,从而提高用户体验. 2.原理 设置img标签的src属性为空或统一的图片路径(如加载中样式),监听页 ...

  3. Vue图片懒加载插件

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

  4. Vue实现一个图片懒加载插件(转载)

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

  5. vue 图片懒加载 vue-lazyload

    图片懒加载 在实际的项目开发中,我们通常会遇见这样的场景:一个页面有很多图片,而首屏出现的图片大概就一两张,那么我们还要一次性把所有图片都加载出来吗?显然这是愚蠢的,不仅影响页面渲染速度,还浪费带宽. ...

  6. Vue图片懒加载

    图片懒加载的原理 先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src).当js监听到该图片元素进入可视窗口时,即将自定义属性 ...

  7. Vue图片懒加载之lazyload插件使用

    当内容没有加载完的时候,用户体验不是很好,这时候,可以使用lazyload这个插件,提升用户体验,使用方法特别简单易用 一. vue lazyload插件: 插件地址:https://github.c ...

  8. VUE图片懒加载-vue lazyload插件的简单上手使用(优化版本)

    在用VUE做项目开发的过程中,首页用到了懒加载的方法,查找了一些方法,觉得官网写得太复杂,有一篇博客不错(https://www.cnblogs.com/xyyt/p/7650539.html),但是 ...

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

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

随机推荐

  1. HAproxy健康检查的三种方式

    1.通过监听端口进行健康检测 .这种检测方式,haproxy只会去检查后端server的端口,并不能保证服务的真正可用. 配置示例: listen http_proxy mode http cooki ...

  2. Bzoj超级经验大放送题集(好评如潮哦~~~)

    其实这些是因为没有数据才形成的...唯一可惜的是这些都是需要300软妹币才能打开的萌萌哒权限题*^_^* 好啦,吾来教你如何快速AC么么哒 pascal: 1 begin end. //Pascal ...

  3. Android: Toolbar、AppBarLayout

    ToolBar是google退出的一个应用程序动作条 包括: 设置导航栏图标 设置应用程序Logo 设置标题 设置子标题 添加各种自定义控件 添加动作条菜单 API:https://developer ...

  4. vector 对象中存放指针类型数据

    <<C++ Primer>> 第四版Exercise Section 5.6 的5.1.6 有一道题是这样的:编写程序定义一个vector对象,其每个元素都是指向string类 ...

  5. 给 Qt 添加模块

    添加 Qt 模块 QtCanvas3D 由于需要使用 Qt Quick 进行 3D 绘图,因此在网上找了一些资料. JS 绘制 3D 的有 ThreeJS 库,应该可以用于 QML.继续搜索,发现Qt ...

  6. Ubuntu 不支持 rpm

    不是第一次犯这个错误了. 记一下. 每次安装jdk 的时候,习惯性下载rpm包. 然后的,然后在 ubuntu上rpm 安装的时候就跪了.. ubuntu需要使用Alien 把rpm 转成 deb再安 ...

  7. 跨平台的.NET邮件协议MailKit组件解析

    发起的.NET Core开源组织号召,进展的速度是我自己也没有想到的,很多园友都积极参与(虽然有些人诚心砸场子,要是以我以前的宝脾气,这会应该被我打住院了吧,不过幸好是少数,做一件事总有人说好,也有人 ...

  8. MySQL基准测试(benchmark)

    基准测试是唯一方便有效的.可以学习系统在给定的工作负载下会发生什么的方法.基准测试可以观察系统在不同压力下的行为,评估系统的容量,掌握哪些是重要的变化,或者观察系统如何处理不同的数据. 验证基于系统的 ...

  9. SQL Server里书签查找的性能伤害

    在我的博客上,以前我经常谈到SQL Serverl里的书签查找,还有它们带来的很多问题.在今天的文章里,我想从性能角度进一步谈下书签查找,还有它们如何拉低你整个SQL Server性能. 书签查找—— ...

  10. 解决使用JavaScriptConvert转换对象为Json时,中文和&符号被转码的问题

    描述:比如 对象为var data=new {url="http://www.baidu.com?a=b&c=d"} 使用JavaScriptConvert序列化为JSON ...