最新要闻
- 每日精选:北京:近期呼吸道合胞病毒感染患儿激增,儿童出现呼吸困难应立即就医
- 用了十几年智能机 终于弄懂了手机掉电快原因_每日动态
- 焦点信息:真是老天爷赏饭吃:女孩特爱哭 被送去唱戏拿了金奖
- 绿源、五星钻豹等电动车这些批次抽查不合格:车速提示音、整车质量没过关|今日热文
- 真要来了?法拉第未来:FF 91车型合规认证按计划进行
- 28年国产武侠游戏IP凉了?《仙剑奇侠传8》被曝未立项
- 维他奶国际发盈喜 预期年度股东应占溢利3500万港元至5500万港元 天天看点
- 天津网约车从业资格实现线上约考
- 单风扇就是好看!RTX 40第一次做成ITX迷你卡 5款集中爆发
- 高颜值87键!影驰Keychron K8 Pro星曜娘联名键盘图赏 全球今头条
- 深圳一大厦异响振动居民被疏散:官方已启动调查_每日热文
- ChatGPT连夜登陆iOS 免费无广告、还支持语音
- 全球今头条!爱马仕推出AirPods Pro保护皮套:售价7100元 够买5个耳机
- 【环球聚看点】奥普光电:公司参与了该项目的机械及装校联调工作
- 欧联杯:塞维利亚胜尤文图斯
- 当前播报:印度:我们的智能手机取得极大成功!苹果等加大布局 曾称接下来靠他们
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
天天动态:记录--axios和loading不得不说的故事
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
loading的展示和取消可以说是每个前端对接口的时候都要关心的一个问题。这篇文章将要帮你解决的就是如何结合axios更加简洁的处理loading展示与取消的逻辑。
首先在我们平时处理业务的时候loading一般分为三种:按钮loading,局部loading,还有全局loading。
(资料图片仅供参考)
按钮loading
其实想写这篇博客的诱因也是因为这个按钮loading ,在大多数时候我们写按钮loading业务的时候是这样写的。
const loading = ref(false)try { loading.value = true const data = await axios.post(`/api/data`)}finally { loading.value = false}
或者这样的写的
const loading = ref(false)loading.value = trueaxios.post(`/api/data`) .then(data => { //do something }) .finally(() => { loading.value = false })
可以看到 我们总要处理loading的开始与结束状态。而且好多接口都要这么写。这样太繁琐了,那我们可不可以这样呢?
vue3版本
const loading = ref(false)const data = await axios.post(`/api/data`,{loading:loading})
把loading的状态给axios统一处理。这样代码是不是就简洁多了呢?处理方式也很简单。
// 请求拦截器axios.interceptors.request.use(config = >{ if (config.loading) { config.loading.value = true }})// 响应拦截器axios.interceptors.response.use( response => { if (response.config.loading) { res.config.loading.value = false } }, error => { if (error.config.loading) { config.loading.value = false } })
我们只需要在axios的拦截器中改变loading的值就可以,注意一定要传入一个ref类的值。这种写法也仅适用于vue3。vue2是不行的。
vue2版本
在vue2里面我们可能会想到这样写。
保存 <script> export default { data () { return { loading: { value: false }, } }, mounted () { const data = await axios.post(`/api/data`,{loading:this.loading}) }, }</script>//拦截器和vue3写法一样
但是很遗憾这样是无法生效的。原因如下
//接口调用axios.post(接口地址,配置项)//拦截器axios.interceptors.request.use(配置项 => {})
在axios中我们接口调用传入的配置项 和 拦截器返回的配置项 并不是同一个内存地址。axios做了深拷贝处理。所以传入的loading对象和返回的loading对象并不是同一个对象。所以我们在拦截器中修改是完全没有用的。
可是vue3为什么可以呢?因为ref返回的对象是RefImpl类的实例 并不是一个普通的对象,axios在做深拷贝的时候没有处理这种实例对象。 所以我们就可以从这里出发来改造一下我们的axios写法。代码如下:
axios代码:
const _axios = axios.create({ method: `post`, baseURL: process.env.VUE_APP_BASE_URL,})//注意:拦截器中比vue3多了个loading!!!// 请求拦截器_axios.interceptors.request.use(config = >{ if (config.loading) { config.loading.loading.value = true }})// 响应拦截器_axios.interceptors.response.use( response => { if (response.config.loading) { res.config.loading.loading.value = false } }, error => { if (error.config.loading) { config.loading.loading.value = false } })export const post = (url, params, config) => { if (config?.loading) { class Loading { loading = config.loading } config.loading = new Loading() } return _axios.post(url, params, config)}
使用方式:
保存 <script> import { post } from "@api/axios" export default { data () { return { //这里的loading可以取任意名字。但是里面必须有value loading: { value: false }, } }, mounted () { const data = await post(`/api/data`,{loading:this.loading}) }, }</script>
可以看到实现的原理也很简单。我们在axios里面把出传入的config中的loading对象也变成一个实例对象就好了。在实例对象中记录我们传入的对象,也是以为这里我们会比vue3的写法多一个loading,从而实现响应式。
高阶函数版本
以上的方案看起来还是很不友好。如果我们不拘泥于在拦截器中封装呢?
axios代码如下:
const _axios = axios.create({ method: `post`, baseURL: import.meta.env.VITE_BASE_URL,})// 请求拦截器_axios.interceptors.request.use()// 响应拦截器_axios.interceptors.response.use()async setRequest (callBack, url, params, config) { //添加按钮的loading if (config.loading) { config.loading.value = true } try { return await callBack(url, params, config) } catch (error) { return Promise.reject(error) } finally { //关闭按钮的loading状态 if (config.loading) { config.loading.value = false } }}export const post = (url, params, config) => { return setRequest(_axios.post,url, params, config)}
以上代码仅仅是个代码思路。我们可以使用高阶函数二次封装 axios的post函数。get等函数也是一样的,这里就不一一举例了。
局部loading
局部loading的添加有两种方式:
- 使用自定义指令 传入true和false 。这样的缺陷是不够灵活,组件内的元素就很难局部添加了, 只能全组件添加。值得一提的是,改变true和false的逻辑就可以用我们上述的按钮loading方法。具体的实现方式这里就不再讲述了,如果需要的话可以评论区留言。
- 在axios中封装。每次调用接口的时候传入需要添加loading的dom。接口调用完毕删除dom。实现方法如下。
这里是vue3 + antdV3 技术栈的一个封装。这里用hooks把设置删除loading的逻辑给拆了出去。
axios代码:
const _axios = axios.create({ method: `post`, baseURL: import.meta.env.VITE_BASE_URL,})const { setLoading, deleteLoading } = useAxiosConfig()// 请求拦截器_axios.interceptors.request.use(config = >{ setLoading(config)})// 响应拦截器_axios.interceptors.response.use( response => { deleteLoading(res.config) }, error => { deleteLoading(res.config) })//这里也可以 不拘泥于拦截器。使用上述高阶函数的方式。export const post = (url, params, config) => { return _axios.post(url, params, config)}
hooks代码
import { createApp } from "vue"import QSpin from "@/components/qSpin/QSpin.vue"import type { RequestConfig, AxiosError } from "@/types/services/http"export default function () { /** 使用WeakMap类型的数据 键名所指向的对象可以被垃圾回收 避免dom对象的键名内存泄漏 */ const loadingDom = new WeakMap() /** * 添加局部loading * @param config */ const setLoading = (config: RequestConfig) => { const loadingTarget = config.dom if (loadingTarget === undefined) return const loadingDomInfo = loadingDom.get(loadingTarget) if (loadingDomInfo) { loadingDomInfo.count++ } else { const appExample = createApp(QSpin) const loadingExample = appExample.mount(document.createElement(`div`)) as InstanceTypeloadingTarget.appendChild(loadingExample.$el) loadingExample.show(loadingTarget) loadingDom.set(loadingTarget, { count: 1, //记录当前dom的loading次数 appExample, }) } } /** * 删除局部loading * @param config */ const deleteLoading = (config: RequestConfig) => { const loadingTarget = config.dom if (loadingTarget === undefined) return const loadingDomInfo = loadingDom.get(loadingTarget) if (loadingDomInfo) { if (--loadingDomInfo.count === 0) { loadingDom.delete(loadingTarget) loadingDomInfo.appExample.unmount() } } } return { setLoading, deleteLoading }}
基础逻辑,很简单。只需要接口请求的时候的添加loading ,接口响应完成的时候删除loading。但是随之而来的就有一个问题,如果多个接口同时请求 或者 一个接口频繁请求需要覆盖的都是同一个dom,这样我们添加的loading就会有很多个相同的,相互覆盖。因此上述代码定义了一个loadingDom 记录当前正在loading的dom有哪些,如果有一样的进来的 就把count加一 ,结束后就把count减一。如果count为零则删除loading。
使用实例代码:
<script setup lang="ts"> import { post } from "@api/axios" import { ref, onMounted } from "vue" const head_dom = ref() const card_dom = ref() //这边写了两个是为了演示下 直接在html标签上面绑定ref拿到的就是dom。在组件上面拿到的是组件实例要$el一下 onMounted(async () => { const data1 = await post(`/api/head`, { dom: head_dom.value }) const data2 = await post(`/api/card`, { dom: card_dom.value.$el }) })</script>我是头部数据我是卡片内容
下面简单解释下hooks代码中QSpin组件的代码。
<script setup lang="ts"> import { Spin } from "ant-design-vue" import { ref } from "vue" const visible = ref(false) const show = (dom: HTMLElement) => { visible.value = true dom.style.transform = dom.style.transform || `translate(0)` } defineExpose({ show })</script>
这里是对antdv3的Spin组件做了一个简单的二次封装。主要讲解的就是一个loading覆盖传入dom的方法。
大多数地方使用的方式都是 relative 和 absolute 定位组合的方式,但是这里采用了transform 和 fixed定位组合的方式。因为我们的项目中可能出现这样一种情况
我是内容
假如 我们要给中间的的div添加loading, 使用relative 和 absolute 定位组合的方式。那么中间的div就会在样式表种添加一个position: relative的属性,这样代码就会变成这样
我是内容
很明显 我们第三层div定位的根节点就从第一层变成了第二层,这样就会有可能导致我们样式的错乱。因此笔者采用了transform 和 fixed定位组合的方式。虽然上述的情况可能还会出现 但是会大大减少出现的可能性。
全局loading
这个就很简单了。如果你封装好了局部的loading 直接在配置项的dom中传入document.body即可!
本文转载于:
https://juejin.cn/post/7215424335719923772
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
关键词:
-
天天热头条丨分享一下mybatisPlus新代码生成器3.5.1以上
pom引入:有MP了就不要再引入mybatis了,会出bug的```xmlcom baomidoumybatis-plus-boot-starter3 5 3 1com
来源: 天天动态:记录--axios和loading不得不说的故事
MySQL 处理重复数据|全球新视野
登录appuploader
天天热头条丨分享一下mybatisPlus新代码生成器3.5.1以上
【金融街发布】人民银行、外汇局:北京、广东、深圳试点优化跨国公司本外币跨境资金集中运营管理政策 天天视讯
每日精选:北京:近期呼吸道合胞病毒感染患儿激增,儿童出现呼吸困难应立即就医
用了十几年智能机 终于弄懂了手机掉电快原因_每日动态
焦点信息:真是老天爷赏饭吃:女孩特爱哭 被送去唱戏拿了金奖
绿源、五星钻豹等电动车这些批次抽查不合格:车速提示音、整车质量没过关|今日热文
真要来了?法拉第未来:FF 91车型合规认证按计划进行
28年国产武侠游戏IP凉了?《仙剑奇侠传8》被曝未立项
维他奶国际发盈喜 预期年度股东应占溢利3500万港元至5500万港元 天天看点
世界快消息!天翼云CDN全站加速产品对websocket协议的支持
【一步步开发AI运动小程序】三、运动识别处理流程
视讯!第三章:存储与检索
SpringBoot实现WebSocket发送接收消息 + Vue实现SocketJs接收发送消息
创新灵感来源于用户实践,TDengine 首次公开四项专利申请 每日消息
天津网约车从业资格实现线上约考
单风扇就是好看!RTX 40第一次做成ITX迷你卡 5款集中爆发
高颜值87键!影驰Keychron K8 Pro星曜娘联名键盘图赏 全球今头条
深圳一大厦异响振动居民被疏散:官方已启动调查_每日热文
ChatGPT连夜登陆iOS 免费无广告、还支持语音
全球今头条!爱马仕推出AirPods Pro保护皮套:售价7100元 够买5个耳机
【环球聚看点】奥普光电:公司参与了该项目的机械及装校联调工作
Qt+QtWebApp开发笔记(二):http服务器日志系统介绍、添加日志系统至Demo测试
易基因:m5C高甲基化介导EGFR突变的非小细胞肺癌耐药潜在机理
焦点热讯:ipa文件怎么安装到iPhone手机上?
ipa文件怎么安装到iPhone手机上?
聊聊Seata分布式事务解决方案的AT模式_每日观察
科创板收盘播报:科创50指数涨0.52% 次新股表现活跃 全球视讯
欧联杯:塞维利亚胜尤文图斯
当前播报:印度:我们的智能手机取得极大成功!苹果等加大布局 曾称接下来靠他们
曝iPhone 15 Plus影像升级为4800万像素:但因良率问题量产延期 今日最新
全球热点!荣耀90系列屏幕升级:首发3840Hz零风险调光护眼屏
环球速讯:53°飞天遭哄抢 茅台自营电商i茅台用户超4000万:销售230亿
1900万没了!一梅赛德斯AMG ONE运输途中被烧成焦炭:原因未明_热消息
海通国际发布先导智能研报
Lerna 备忘清单_开发速查表分享
CF1512D Corrupted Array 题解 天天观点
全球实时:Blazor实战——Known框架快速开始
【解决方法】家用路由器的复位/重置(reset)操作,解决管理员后台密码遗忘
当前快播:睡觉时枕边有手机会得脑瘤吗?网友吵翻:没明确答案 你怎么看?
纯白机身 颜值天花板!魅族20告白礼盒上架:3199元起_世界今头条
王小川:10年后机器智慧会超过人类 AI迭代周期成倍递减
并非“大更新”?消息称Win11 23H2仅基于22H2优化改进
每日时讯!焦点科技李磊:小语种覆盖全球超5万亿美元的市场
测试管理快速入门
【天天新要闻】上海丨阿里云 Serverless 技术实战营邀你来玩!
环球今日报丨360浏览器修改主页不会动_360浏览器修改主页
你会买吗?一块京A摩托车牌照价格涨破50万:揭秘为何要这么贵?-天天快播
医生用一根针帮患癌老人冻死肿瘤 网友称神奇:以为是中医针灸
生理期可以喝普洱茶吗_生理期有绝对禁忌事项吗_快消息
Centos7 设置定时任务
泰国进口乳胶!网易严选乳胶垫、枕头大促:54元起
iQOO Pad搭载12.1英寸巨屏:2.8K分辨率、144Hz高刷 当前要闻
【世界聚看点】华为5倍薪酬再招天才少年!任正非:破题能力最重要 不是综合素质
当前视点!520用更好的长焦镜头表达爱意:华为P60 Pro长焦人像 让爱不分昼夜
华为新款家庭存储支持断电保护电源:停电自动关机、来电自动开机_世界球精选
观速讯丨2023中央财经大学在职课程培训班怎么样?
【GPT-4理论篇-1】GPT-4核心技术探秘
软件工程快速入门(下)-天天实时
环球热消息:聊聊分布式事务一致性与本地消息表
西门豹人物简介卡_西门豹人物简介
豹子闯入印度男子家中偷狗 狗主人惊醒淡定玩手机 网友:心真大
无限复制没了?《塞尔达传说:王国之泪》1.1.1更新发布:修复主线任务Bug_天天新动态
前高管唱衰:苹果MR设备将是史上最糟糕的产品之一 天天观天下
当前播报:裁员超千人后 长安福特又被曝裁减百万产能
曾致两死一伤!台州特斯拉事故歪曲事实视频作者致歉 全球独家
斗罗大陆剧场版最终预告公布,海神大战天使神,还有专属主题曲
通讯!软件工程快速入门
每日资讯:技术干货|如何利用 ChunJun 实现数据离线同步?
快看:腾讯云的devops自动化部署代替jenkins
双检锁(DCL)实现懒汉单例模式_全球讯息
网传云南一公园有多人用针扎小象,园方回应:已反馈了该情况,有关部门在协助调查
1199元起 雷蛇天狼星V2专业版游戏音箱发布:背投式RGB|当前最新
多芬广告呼吁女性游戏角色不必性感 宣传女性身材自信 引玩家众怒|世界热头条
openai为chatgpt人工智能推出ios应用
兑现“十年合约”:微软正式开启与NVIDIA合作
菜鸟CEO万霖发全员信:开启新创业征程 建设全球领先数智物流集团-天天热门
一机搞定全屋清洁!石头智能洗地机A10 Ultra图赏
日本4月份贸易赤字4324亿日元 信息
JS函数中的属性-全球简讯
【天天速看料】ET介绍——事件机制EventSystem
聊聊Sentinel的熔断降级
速讯:30多万买豪华行政车 新一代凯迪拉克CT6内饰官图:超帅9k曲面屏上车
《王者荣耀》520亚瑟新皮肤太过250:开局一条狗 玩家直呼要买
马克思主义理论专业大学排名(马克思主义专业大学排名及分数线)_世界最新
ChatGPT正式登陆iOS!但苹果却禁止员工使用-当前快报
科普:相机镜头的“放大倍率”是什么?
真我GT Neo5 SE“圣白幻影”配色亮相:颜值质感拉满|全球热推荐
项目管理快速入门
实时:聊聊Mybatis集成Spring的原理
SSM整合使用 天天信息
观速讯丨南微医学:5月18日融资买入1167.84万元,融资融券余额2.55亿元
华为凌霄子母路由Q6E开启预售:499元 每个房间都Wi-Fi满格
电动车价格战还打不打?电池级碳酸锂翻倍式触底反弹 重返30万元/吨 当前聚焦
网传云南一公园多人用针扎小象引围观 官方回应:网友呼吁不要再看动物表演
好消息!罗马后卫切利克赛后表示:我很好,伤势并不严重
JMeter性能测试工具快速入门教程
【读财报】4月猪价微降 上市猪企销量、收入环比变动较小