调用方式,express写个后台服务调图片,具体使用不贴了

import VueLazyload from "./modules/vue-lazyload";Vue.use(VueLazyload,{loading: 'http://localhost:3000/images/loading.gif',error: 'http://localhost:3000/images/error.jpg',preload: 1 // 倍数
});

使用指令

<img v-lazy="item.src" :alt="item.title">

vueLazyload/index.js

import Lazyload from './Lazyload';
const VueLazyload = {install(Vue, options) {const LazyClass = Lazyload(Vue)const lazyload = new LazyClass(options);Vue.directive('lazy', {bind: lazyload.bindLazy.bind(lazyload)})}
}
export default VueLazyload;

vueLazyload/Lazyload.js

import Lazyimg from "./Lazyimg";
import {getScrollParent
} from "./utils";// 柯里化
export default function Lazyload(Vue) {return class Lazy {constructor(options) {this.options = options;this.isAddScrollListener = false;this.lazyImgPool = [];}bindLazy(el, bindings, vnode) {// console.log(this.options);// 还未渲染Vue.nextTick(() => {const scrollParent = getScrollParent(el);// console.log('scrollParent', scrollParent);if (scrollParent && !this.isAddScrollListener) {scrollParent.addEventListener('scroll', this.handleScroll.bind(this), false)//true 表示在捕获阶段调用事件处理程序,false(默认值)表示在冒泡阶段调用事件处理程序}const lazyImg = new Lazyimg({el,src: bindings.value,options: this.options,imgRender: this.imgRender.bind(this)})// 图片池this.lazyImgPool.push(lazyImg);this.handleScroll(); // 初始化时显示一部分可视区域内的图片})}handleScroll() {let isVisible = false;this.lazyImgPool.forEach(lazyImg => {if (!lazyImg.loaded) { // 未加载isVisible = lazyImg.checkIsVisible() //检测是否出现在区域内isVisible && lazyImg.loadImg() // 出现了加载图片}})}imgRender(lazyImg, state) {const {el,options} = lazyImg;const {loading,error} = options;let src = '';switch (state) {case 'loading':src = loading || '';break;case 'error':src = error || '';break;default:src = lazyImg.src;break;}el.setAttribute('src', src);}}
}

vueLazyload/Lazyimg.js

/* 处理每张图片的类 */
import {imgLoad
} from "./utils";
export default class Lazyimg {constructor({el,src,options,imgRender}) {this.el = elthis.src = srcthis.options = optionsthis.imgRender = imgRender //渲染事件this.loaded = false //加载完没this.state = { // 状态loading: false,error: false}}checkIsVisible() {// 当前图片距离最顶端距离是多少来判断const {top} = this.el.getBoundingClientRect();return top < window.innerHeight * (this.options.preload || 1.3); // 小于倍数}loadImg() {this.imgRender(this.el, 'loading');imgLoad(this.src).then(() => {this.state.loading = true;this.imgRender(this, 'ok');this.loaded = true;}, () => {this.state.error = true;this.imgRender(this, 'error');this.loaded = true;})}
}

vueLazyload/utils.js

export function getScrollParent(el) {let _parent = el.parentNode;while (_parent) {// 查找父节点是否有style overflow:autoconst styleOverflow = window.getComputedStyle(_parent)['overflow'];if (/(scroll)|(auto)/.test(styleOverflow)) {return _parent;}_parent = _parent.parentNode;}
}
export function imgLoad(src) {return new Promise((resolve, reject) => {const oImg = new Image();oImg.src = src;oImg.onload = resolve;oImg.onerror = reject;})
}

手写vue2的Lazyload相关推荐

  1. 前端进阶-手写Vue2.0源码(三)|技术点评

    前言 今天是个特别的日子 祝各位女神女神节快乐哈 封面我就放一张杀殿的帅照表达我的祝福 哈哈 此篇主要手写 Vue2.0 源码-初始渲染原理 上一篇咱们主要介绍了 Vue 模板编译原理 它是 Vue ...

  2. 【手写 Vue2.x 源码】第二十八篇 - diff 算法-问题分析与 patch 优化

    一,前言 首先,对 6 月的更文内容做一下简单回顾: Vue2.x 源码环境的搭建 Vue2.x 初始化流程介绍 对象的单层.深层劫持 数组的单层.深层劫持 数据代理的实现 对象.数组数据变化的观测 ...

  3. 【手写 Vue2.x 源码】第十八篇 - 根据 render 函数,生成 vnode

    一,前言 上篇,介绍了 render 函数的生成,主要涉及以下两点: 使用 with 对生成的 code 进行一次包装 将包装后的完整 code 字符串,通过 new Function 输出为 ren ...

  4. 【手写 Vue2.x 源码】第十九篇 - 根据 vnode 创建真实节点

    一,前言 上篇,根据 render 函数,生成 vnode,主要涉及以下几点: 封装 vm._render 返回虚拟节点 _s,_v,_c的实现 本篇,根据 vnode 虚拟节点渲染真实节点 二,根据 ...

  5. 【手写 Vue2.x 源码】第二十二篇 - dep 和 watcher 关联

    一,前言 上篇,主要介绍了 Vue 依赖收集的过程分析: 介绍了 Vue 的响应式特性 介绍了 Vue 的依赖收集过程 介绍了 dep 和 watcher 以及观察者模式: 本篇,Vue 依赖收集的实 ...

  6. 【手写 Vue2.x 源码】第三十一篇 - diff 算法 - 比对优化(下)

    一,前言 上篇,diff 算法-比对优化(上),主要涉及以下几个点: 介绍了如何对儿子节点进行比对: 新老儿子节点可能存在的 3 种情况及代码实现: 新老节点都有儿子时,diff 的方案介绍与处理逻辑 ...

  7. Vue2.0 + ElementUI 手写权限管理系统后台模板(一)——简述

    简介 这个权限管理就是为了方便,跟系统安全真的不沾边,只是根据后台返回的角色信息来生成他可以看见的菜单和按钮,显示菜单的方法是根据权限删除掉路由表里没有权限的路由,然后再动态添加,原本包含没有访问权限 ...

  8. 超级详细的手写webpack4配置来启动vue2项目(附配置作用)

    基础目录结构以及各个文件的作用 初始npm项目 npm init 一路回车,一律使用默认的npm项目配置 package.json修改scripts 如下: {"name": &q ...

  9. Vue2.0 + ElementUI 手写权限管理系统后台模板(三)——页面搭建

    框架布局 本章只介绍基础布局,和一些主要的js,页面上基本上都是些交互事件,项目代码上都有注释,不懂的地方debug跑一变就知道了,只是这些事件基本上没有独立存在的,相互之间都有关联 框架风格 新建页 ...

最新文章

  1. SQL Server2005重装Performance Monitor Counter 的问题解决
  2. swagger报错 java.lang.NumberFormatException: For input string: ““
  3. 在同一个Linux上配置多个git账户
  4. 【转】VS中常用图标提示含义
  5. lr 中cookie的解释与用法
  6. javaweb各种乱码问题处理
  7. 卸载 Visual Studio 2005步骤
  8. 基于 Jenkins + JaCoCo 实现功能测试代码覆盖率统计
  9. IDEA中.properties配置文件输入中文显示Unicode编码,本地编辑器,服务器打开显示Unicode编码问题解决方案
  10. Photoshop 入门教程「3」如何缩放和平移图像?
  11. attrib批量显示文件夹_CMD中使用attrib命令设置文件只读、隐藏属性详解
  12. html选择时间区间控件,Html5添加用户选择一个日期时间范围的日期选择器插件教程...
  13. 线性回归 T检验P值计算
  14. envi 监督分类超详细过程
  15. html如何给标题设置边框和底纹,word如何设置文字边框和底纹
  16. PUBWIN密码攻防战 打造永攻不破的密码!(转)
  17. Python骚操作:Python控制Excel实现自动化办公
  18. 从平头哥讲起,谈谈全域旅游,说说为什么要做全栈工程师
  19. docker-compose Seata+Nacos部署
  20. win10的C盘满了清理方法

热门文章

  1. hadoop设置ssh免密码登录
  2. linux内核驱动模块开发makefile实例解析
  3. alexnet vgg_从零开始:建立著名的分类网2(AlexNet / VGG)
  4. C语言高级编程:大端模式和小端模式(Big-Endian和Little-Endian)
  5. C语言高级编程:二级指针的赋值
  6. Ubuntu开启telnet服务
  7. 捡到银行卡套取密码取现1万多元,犯了信用卡诈骗罪被判7个月
  8. 新版征信报告实施之后,信用卡养卡套现真的要凉凉了?
  9. 2018年对PHP的新认知
  10. HTTP API领域在围绕OAS进行整合