图片懒加载(自定义指令)

-----------------------------------------------------------

  • 图片懒加载
    • 自定义指令
    • 使用mock模拟随机图片
    • 列表组件如下(主要内容):
    • 配置自定义指令

图片懒加载

实现思路

使用自定义指令实现通用图片懒加载(在图片到达视口内时再进行加载)

自定义指令

可以理解为另一个生命周期,在各个钩子函数中处理相关内容,常用的钩子函数如下

// 自定义指令配置
export default {// 只调用一次,指令第一次绑定到元素时调用bind(el,boundings){// 处理},// 被绑定元素插入父节点时调用 inserted(el,boundings){// 处理},// 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前update(el,boundings){// 处理}// 只调用一次,指令与元素解绑时调用unbind(el){// 处理}
}

通常是使用对象来配置,当bind钩子与update钩子内容一致,而不关心其它的钩子时可以简写为函数配置:

// 自定义指令配置
export default function(el,boundings){// 处理
}

使用mock模拟随机图片

Mock.mock(/^\/api\/blog(\?.+)?$/,"get",function(options){// 使用动态模拟数据const query = qs.parse(options.url);return Mock.mock({"code": 0,"msg": "string","data": {"total|200-800": 0,[`rows|${query.limit||10}`]: [{"id": "@guid","title": "@ctitle","description": "@cparagraph(1,10)","createDate": "@date('T')","scanNumber|1000-10000": 0,"commentNumber|0-400": 0,"category": {"id|0-10": 0,"name": "分类@id"},"thumb|1": ["@image(300x250,@color,#fff,@natural)",null]}]}})
})

列表组件如下(主要内容):

<template><div class="bloglist-container" v-loading="isLoading" ref="bloglistRef"><ul class="list"><li class="item" v-for="item in data.rows" :key="item.id"><router-link :to="{name: '/blogDetail',params: {id: item.id}}"><div class="img"  v-if="item.thumb"><!-- 绑定自定义指令 --><img :src="item.thumb" class="image" v-lazy="item.thumb"></div></router-link><div :class="item.thumb?'txt':'ptxt'"><router-link :to="{name: '/blogDetail',params: {id: item.id}}"><h2 class="title">{{ item.title }}</h2></router-link><div class="info"><span>日期:{{ formatDate(item.createDate) }}</span><span>浏览:{{ item.scanNumber }}</span><span>评论:{{ item.commentNumber }}</span><router-link :to="{name:'/categoryBlog',params: {categoryId: item.category.id}}"><span class="cate">分类:{{ item.category.id }}</span></router-link></div><p class="desc">{{ item.description }}</p></div></li></ul><Pager :current="this.page" :total="data.total" :limit="this.limit" @pageChange="handlePageChange"/></div>
</template><script>
import * as blogApi from '@/api/blog.js'
import fetchData from '@/mixins/fetchData';
import { formatDate } from '@/utils/formatDate';
import Pager from '@/components/Pager';
import scrollEvent from '@/mixins/scrollEvent';
export default {mixins: [fetchData({}),scrollEvent("bloglistRef")],components: {Pager,BackTop},computed:{page(){return +this.$route.query.page || 1;},limit(){return +this.$route.query.limit || 10;},categoryId(){return +this.$route.params.categoryId || -1;}},methods:{// 获取文章列表async getFetchData(){return await blogApi.getBlog(this.page,this.limit,'',this.categoryId);},formatDate,},
}
</script>

在这里插入图片描述

配置自定义指令

使用一个数组保存ajax获取的所有列表元素相关内容,然后在元素插入父组件时先进行一次处理,将初始就在视口的图片加载,已经加载完毕的元素相关内容会被数组删除,然后通过滚动事件来进行图片处理,最后进行事件清除,具体如下:

import defaultImg from '@/assets/default.gif';
import eventBus from '@/eventBus';
import {deBounce} from '@/utils'// 刚开始ajax获取的所有图片相关节点、src都在内,处理后会被此数组剔除
let imgs = [];      // 需要处理的图片数组/*** 处理图片,先赋值默认图片,如在视口内则加载源图片* @param {*} i 数组内容,包含该元素dom,以及图片源src*/
function setImage(i){// 先使用默认图片i.dom.src = defaultImg;// 判断是否位于视口内const clientHeight = document.documentElement.clientHeight;const domTop = i.dom.getBoundingClientRect().top;const domHeight = i.dom.getBoundingClientRect().height || 250;// console.log(clientHeight,domTop,domHeight);if(domTop >= -domHeight && domTop <= clientHeight){// 在视口内i.dom.src = i.src;// 处理完成后清除数组中相关内容imgs.filter((img)=> img!==i);}}
/*** 批量处理所有图片*/
function setImages(){for (const i of imgs) {setImage(i);}
}
/*** 用于触发setImages*/
function handleScroll() {setImages();}// 事件总线监听滚动
eventBus.$on('blogMainScroll',deBounce(handleScroll,50));// 自定义指令配置
export default {// 被绑定元素插入父节点时调用 inserted(el,boundings){const img = {dom: el,src: boundings.value};imgs.push(img);setImage(img)  // 处理最开始的数组内容},// 只调用一次,指令与元素解绑时调用unbind(el){// 处理结束后,清除数组内相关内容,避免重复处理imgs = imgs.filter((img) => img.dom !== el);}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/822.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

三层交换技术,eNSP实验讲解

三层交换技术&#xff0c;eNSP实验讲解 一、简要介绍1、概念2、工作原理3、优点4、应用场景5、与路由器的区别 二、eNSP仿真实验1、步骤一&#xff1a;创建连接&#xff0c;明确参数。2、步骤二&#xff1a;设置PC1和PC2参数3、步骤三&#xff1a;配置交换机&#xff0c;通过命…

扫雷(C语言)

目录​​​​​​​ 前言 一、前提知识 二、扫雷游戏编写 2.2 test文件基本逻辑 2.2.1菜单编写 2.2.2game函数的逻辑 2.2.2.1定义两个数组 2.2.2.2两个数组数组的初始化 2.2.2.3打印棋盘 2.2.2.4布置雷 2.2.2.5排查雷 2.2.2.6获取坐标附近雷的数量 2.2.2.7什么时候…

Node.js:模块 包

Node.js&#xff1a;模块 & 包 模块module对象 包npm安装包配置文件镜像源 分类 模块 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说&#xff0c;模块是可组合、分解和更换的单元。 简单来说&#xff0c;就是把一个…

恋爱脑学Rust之dyn关键字的作用

在 Rust 语言中&#xff0c;dyn 关键字允许我们在使用特征时创建“动态派发”——即通过一个统一的接口操作多种类型的具体实现。可以把它理解成一种“浪漫的妥协”&#xff1a;当我们不知道未来会爱上谁&#xff0c;只知道对方一定具有某种特征时&#xff0c;dyn 就像一个协议…

vue3项目中实现el-table分批渲染表格

开篇 因最近工作中遇到了无分页情景下页面因大数据量卡顿的问题&#xff0c;在分别考虑并尝试了懒加载、虚拟滚动、分批渲染等各个方法后&#xff0c;最后决定使用分批渲染来解决该问题。 代码实现 表格代码 <el-table :data"currTableData"borderstyle"wi…

Qt自定义控件:汽车速度表

1、功能 制作一个汽车速度表 2、实现 从外到内进行绘制&#xff0c;初始化画布&#xff0c;画渐变色外圈&#xff0c;画刻度&#xff0c;写刻度文字&#xff0c;画指针&#xff0c;画扇形&#xff0c;画内圈渐变色&#xff0c;画黑色内圈&#xff0c;写当前值 3、效果 4、源…

语音识别:docker部署FunASR以及springboot集成funasr

内容摘选自: https://github.com/modelscope/FunASR/blob/main/runtime/docs/SDK_advanced_guide_offline_zh.md FunASR FunASR是一个基础语音识别工具包&#xff0c;提供多种功能&#xff0c;包括语音识别&#xff08;ASR&#xff09;、语音端点检测&#xff08;VAD&#xf…

鸿蒙进阶篇-模态转场

hello大家好&#xff0c;这里是鸿蒙开天组&#xff0c;今天让我们来学习鸿蒙进阶篇-模态转场 模态转场 今天来学习模态转场&#xff0c;就是页面中弹出&#xff0c;全屏&半屏的弹框&#xff1a; 就像这样&#xff0c;模态转场主要分为半模态和全屏模态&#xff0c;上面的…

RGA DEMO 下部

#加载llm模型通过ollama最好别用ollama我是没经济条件 from langchain_community.llms import Ollama llm Ollama(model"qwen1_5-4b-chat-q2_k")#pip install langchain_ollama -i https://pypi.tuna.tsinghua.edu.cn/simple #OllamaEmbeddings 要写地址本地也要写&…

Faces in Things数据集: 由麻省理工学院、微软等联合发布,探索人类视觉错觉的新里程碑

2024-09-24&#xff0c;由麻省理工学院、微软、丰田研究院、NVIDIA联合发布的 Faces in Things&#xff0c;为我们打开了研究人类视觉错觉——尤其是面部错觉&#xff08;Pareidolia&#xff09;的新篇章。专注于人类视觉系统如何在各种随机刺激中检测到类似面孔的结构&#xf…

知识见闻 - Workday公司介绍

人力资源“一哥”Workday的前世今生 01 Duffield 既然要聊Workday&#xff0c;我们首先要认识一个人。David Duffield&#xff0c;又一位企业软件服务行业的绝对大神。 大卫杜菲尔德&#xff08;David Duffield&#xff09;出生于1941年。 40岁&#xff0c;很多职场人都已经认命…

宁德时代嵌入式面试题及参考答案(万字长文)

vector 和 list 的主要区别是什么&#xff1f; 向量&#xff08;vector&#xff09;和链表&#xff08;list&#xff09;是 C 中两种常用的容器。 从底层数据结构来讲&#xff0c;vector 是基于连续的内存存储的动态数组。这使得它可以通过索引快速访问元素&#xff0c;时间复杂…

设计模式08-行为型模式1(命令模式/迭代器模式/观察者模式/Java)

五、行为型模式 **行为模式的定义&#xff1a;**行为型模式是对不同的对象之间划分职责和算法的抽象化。行为型模式定义了系统中对象之间的交互与通信&#xff0c;研究系统在运行时对象之间的相互通信与协作&#xff0c;进一步明确对象的职责&#xff0c;包括对系统中较为复杂的…

【设计模式】结构型模式(二):代理模式

结构型模式&#xff08;二&#xff09;&#xff1a;代理模式 3.代理模式&#xff08;Proxy&#xff09;3.1 主要特点3.2 组成部分3.3 示例代码3.3.1 Subject 接口3.3.2 RealSubject 实际对象3.3.3 Proxy 代理对象3.3.4 客户端代码3.3.5 运行结果 3.4 总结 3.代理模式&#xff0…

第二十八章 Vue之自定义指令

目录 一、引言 二、自定义指令的注册和使用方式 2.1. 自定义指令-全局注册使用 2.2. 自定义指令-局部注册使用 三、自定义指令完整代码 3.1. 自定义指令全局注册/使用 3.1.1. main.js 3.1.2. App.vue 3.2. 自定义指令局部注册/使用 3.2.1. main.js 3.2.2. App.vue …

Charles简单压力测试

1.接口请求次数&#xff0c;并发量&#xff0c;请求延迟时间均可配置 1.1选中需要进行测试的接口&#xff0c;鼠标右键选中【repeat advance】 2.设置并发参数 下面的图中&#xff0c;选择了1个接口&#xff0c;每次迭代中1个接口同时请求&#xff0c;迭代1000次&#xff08;…

【uniapp3】分享一个自己写的h5日历组件

简言 分享一下自己基于uniapp写的日历组件。如果不太满足你的需求&#xff0c;可以自己改造。 日历 实现分析&#xff1a; 页面显示 - 分为顶部显示和日历显示&#xff0c;我这里做了多行和单行显示两种情况&#xff0c;主要是当时看着手机的日历做的&#xff0c;手机上的…

Java设计模式(代理模式整理中ing)

一、代理模式 1、代理模式定义&#xff1a; 代理模式&#xff1a;由于某些原因要给某对象提供一个代理以控制对该对象的访问&#xff0c;这时访问对象不适合或者不能够直接引用目标对象&#xff0c;代理对象作为访问对象与目标对象之间的中介进行连接调控调用。 2、代理模式的…

Thumb 汇编指令集,Thumb 指令编码方式,编译 Thumb 汇编代码

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ Thumb指令集 ARM 指令集&#xff1a;最早在 1985 年随第一代 ARM 处理器问世。ARM 指令集一开始是 32 位固定长度的指令&#xff0c;用于各种计算任务。 Thu…

Leetcode - 周赛421

目录 一&#xff0c;3334. 数组的最大因子得分 二&#xff0c;3335. 字符串转换后的长度 I 三&#xff0c;3336. 最大公约数相等的子序列数量 四&#xff0c;3337. 字符串转换后的长度 II 一&#xff0c;3334. 数组的最大因子得分 暴力方法就不演示&#xff0c;这里介绍一个…