对于vue项目而言,图片懒加载是一个常见的图片加载方案,可以优化用户体验,而vue-lazyload则是一个广泛使用的插件。
 对于某些业务场景,我们需要监听图片加载失败事件,而后进行相应的处理,然而无论是官方文档还是网络上的解决方案都不直观甚至有错误,开发者不经过一番探索,很难知道如何处理,甚至怀疑该插件是否能监听加载失败事件。笔者经过一番探索,所幸的是,发现该问题终究是能够解决的,现将相关解决方案分享如下。

业务场景

试想这样的场景:

在img标签上,使用v-lazy绑定的图片的地址。图片的地址可能有误,图片可能因此加载失败。这时,我们需要重新给图片赋予新的正确地址,使图片加载出来。应该如何处理?

你可能持有怀疑,为什么图片地址会不正确呢?事实上,对某些技术架构而言,的确有可能,例如:

图片的源文件非常大,可能达到几十M,这时我们不会加载源文件地址,而是加载缩略图,缩略图的体积大大减小,利于我们提升用户体验,缩小等待时间。然而,缩略图是由阿里云oss提供的服务,它会自动为我们进行图片裁剪,得到缩略图,不过源文件限制在20M以内。这样,当我们加载缩略图时,如果源文件的尺寸大于20M,缩略图就不会存在,使得图片加载失败,这时我们需要加载源文件地址。

当上述情况发生时,我们就需要监听vue-lazyload的图片加载失败事件,重新请求源文件地址了。

常见解决方案分析

1.使用filter选项,修改源文件地址

在官方文档中,做了示例,可以通过filter选项修改图片地址。问题在于,该方案无法检测图片源文件的尺寸,也无法判断指定图片地址是否存在。如果要通过请求探测指定地址的图片是否存在,则会使得加载时间大大加长,不利于用户体验。并且针对全局生效,很难针对各种情况做合理配置。

2.使用adapter选项,监听error事件

我们可以通过adapter的error选项,监听到图片加载失败。但是当这个时候,我们无论做什么,都无法使图片重新加载,即便我们修改了图片源地址,一切已成定局,因此行不通。同样该选项针对全局生效,难以做个性化配置。

3.使用vm.$Lazyload.$onvm.$Lazyload.$once监听error事件

对于这两个选项而言,我们可以在vue的组件实例中,通过this.$Lazyload.$oncethis.$Lazyload.$on来进行监听error事件,因为他们已经挂载到Vue的原型上。
然而,经笔者实测,这两个事件虽然会触发,然而触发的时机和次数却与预期并不相同。当笔者对40张图片使用了懒加载时,即便只有几张图片地址错误,这两个事件也会反复触发,达到几十次甚至于几百次。因此,大胆断言,这两个事件的设计并不是为了监听图片加载失败或成功来进行相关处理。

(当然,不排除笔者没有领会设计者意图的可能,如果你使用这两个事件成功了,请告知。)

推荐解决方案:dispatchEvent + @error

我们只需要做两个地方的处理,就能达到预期。首先是对vue-lazyload做全局配置,开启dispatchEvent选项:

Vue.use(VueLazyload, {loading: require("@/assets/images/lazy-loading.svg"),error: require("@/assets/images/lazy-loading.svg"),dispatchEvent: true,attempt: 1
});

在以上情况下,我们将dispatchEvent设置为true,表明开启img的原生dom事件,默认情况下,该选项是false,是不会开启原生dom事件的。这样,我们现在可以监听img的原生error事件:

<template><div class="card"><div class="card-img"><imgv-lazy="thumbImgUrl"alt=""@click="onPreview"v-if="showThumb"@error="handleLazyErr"/><img v-lazy="data.imgUrl" alt="" @click="onPreview" v-else /><el-image-viewerv-if="showViewer":on-close="closeViewer":url-list="[previewImgUrl]"/></div><div class="card-name">{{ data.name }}</div></div>
</template><script>
import ElImageViewer from "element-ui/packages/image/src/image-viewer";export default {name: "",components: { ElImageViewer },props: {data: {type: Object,default() {return {};}}},data() {return {showThumb: true,showViewer: false};},methods: {onPreview() {this.showViewer = true;},// 关闭查看器closeViewer() {this.showViewer = false;},// 监听加载失败handleLazyErr() {setTimeout(() => {this.showThumb = false;}, 2000);}},computed: {// 原图太大,显示缩略图thumbImgUrl() {return `${this.data.imgUrl}?x-oss-process=image/resize,h_355,w_268`;},previewImgUrl() {let url;if (this.showThumb) {url = `${this.data.imgUrl}?x-oss-process=image/resize,w_1920`;} else {url = this.data.imgUrl;}return url;}}
};
</script>

现在,在以上案例中,我们通过监听到图片加载失败触发原生的error事件,来加载图片源文件,这样就比较巧妙的实现了失败时显示原图的需求。

本文完。

vue图片懒加载插件vue-lazyload监听加载失败事件的解决方案相关推荐

  1. vue图片懒加载vue-lazyload

    vue图片懒加载vue-lazyload 需求描述 功能实现 需求描述 图片过大,加载缓慢,图片懒加载,添加Loading状态,优化展示效果. 功能实现 1.安装vue-lazyload npm in ...

  2. web前端面试高频考点——Vue原理(理解MVVM模型、深度/监听data变化、监听数组变化、深入了解虚拟DOM)

    系列文章目录 内容 参考链接 Vue基本使用 Vue的基本使用(一文掌握Vue最基础的知识点) Vue通信和高级特性 Vue组件间的通信及高级特性(多种组件间的通信.自定义v-model.nextTi ...

  3. 基于腾讯 x5 开源库,提高 webView 开发效率,大概要节约你百分之六十的时间成本。该案例支持处理 js 的交互逻辑且无耦合、同时暴露进度条加载进度、可以监听异常 error 状态、支持视频播放

    YCWebView 项目地址:yangchong211/YCWebView 简介: 基于腾讯 x5 开源库,提高 webView 开发效率,大概要节约你百分之六十的时间成本.该案例支持处理 js 的交 ...

  4. Vue + Element UI——监听DOM元素高度和宽度解决方案整理(八种方法)

    问题描述 监听DOM元素大小的变化,在前端开发中,算是一个比较常见的需求,比如我们要制作可伸缩的图表的时候,可能需要根据DOM大小的变化,进行动态的更新图表. 解决方案 方法一: 监听window变化 ...

  5. vue中使用饿了么input组件监听回车事件不起作用

    vue使用element-ui的el-input监听不了回车事件,原因是element-ui自身封装了一层input标签之后,把原来的事件隐藏了,加上.native可以监听到组件根元素的原生事件 转载 ...

  6. 微信浏览器返回刷新,监听微信浏览器返回事件,网页防复制,移动端禁止图片长按和vivo手机点击img标签放大图片

    以下代码都经过iphone7,华为MT7 ,谷歌浏览器,微信开发者工具,PC端微信验证.如有bug,还请在评论区留言. demo链接:https://pan.baidu.com/s/1c35mbjM ...

  7. [react] 组件卸载前,加在DOM元素的监听事件和定时器要不要手动清除?为什么?

    [react] 组件卸载前,加在DOM元素的监听事件和定时器要不要手动清除?为什么? 定时器要在 componentWillUnmount 手动清除,直接绑定在JSX里的事件监听器不用,使用ref绑定 ...

  8. Vue 图片懒加载 之 Vue-Lazyload

    一.什么叫懒加载 通俗讲 : 懒加载就是延时加载,即当需要用到的时候再去加载. 那什么叫做需要用到的时候? 比如一个图片在没有出现在可视区域内,就已经加载当页面里了, 但只有滚动页面下方式才能看见, ...

  9. vue 图片懒加载和懒加载原理

    在真实图片得到之前,展示懒加载设置的图片1.安装cnpm i vue-lazyload -S2.main.jsimport VueLazyload from 'vue-lazyload'Vue.use ...

最新文章

  1. 2021年大数据Flink(二十八):Flink 容错机制 自动重启策略和恢复
  2. java中的基本用法
  3. JVM与Dalvik
  4. 【原创】android——SQLite的cmd命令的基本操作
  5. sql server自动备份
  6. Leetcode——1. Two Sum
  7. SAP License:为什么一些现有成熟客户不愿意上S/4
  8. mysql迁移数据目录,这个坑你遇到过吗?
  9. WPF 获取程序路径的一些方法,根据程序路径获取程序集信息
  10. 【杂题总汇】HDU多校赛第十场 Videos
  11. springboot全局异常处理_SpringMVC全局异常处理
  12. Flink流处理框架下的交通灯控制器
  13. 当Godot游戏引擎遇上物联网,可以开出怎样的花
  14. 关于FBG、TFBG、LPG、45°TFBG、EX-45°TFBG
  15. 循环(环形)缓冲区之Boost::circular_buffer
  16. 约束——非空约束和唯一性约束
  17. java生成pdf文件流_java 已经获取pdf代码,如何把他pdf文件保存到本机 要求用输出流做...
  18. 淘宝反腐!26家网店因贿赂淘宝小二被关停
  19. windows7旗舰版32位JAVA安装_Windows7旗舰版32位Oracle10g的安装和卸载
  20. React Native 之项目的启动

热门文章

  1. 计算机音乐谱东演员,计算机音乐谱光辉岁
  2. 使用HSqlDB的SQL/JRT功能
  3. 安装dreamwaver
  4. qt无边框窗体的移动
  5. win10笔记本或电脑WLAN密码忘记了不怕,【win10】查看以前连接过的wifi密码
  6. 知乎爬虫|既然所有的生命都要死亡,那么生命的意义是什么?
  7. 论文笔记--Inductive Graph Neural Networks for Spatiotemporal Kriging
  8. Python 中 ‘unicodeescape’ codec can’t decode bytes in position XXX: trun错误原因分析及解决方案
  9. android 外接USB扫码器应用闪退解决方法
  10. Python画玫瑰花,七夕礼物。