vue3中通过自定义指令实现loading加载效果

前言

在现代Web开发中,提升用户体验一直是开发者们追求的目标之一。其中,一个常见的场景就是在用户与应用程序进行交互时,特别是当进行异步操作时(如网络请求),为用户提供即时的反馈,避免用户因为等待而感到困惑或不满。这通常通过显示一个加载指示器(通常称为Loading效果)来实现。本文将深入探讨如何在Vue 3中通过自定义指令的方式来实现Loading加载效果。自定义指令是Vue提供的一种强大工具,允许我们在Vue模板中附加自定义行为。通过自定义指令,我们可以轻松地创建可复用的、可配置的加载效果组件,并将其应用于任何需要显示加载状态的元素上。

演示效果图

image.png

新建index.vue文件

components目录下新建loading目录,并在loading目录下新建index.vue文件

<template><div class="loading-container" v-if="show"><div class="loader"></div><div class="tips">正在快马加鞭的加载中....</div></div>
</template><script setup name="Loading">
const show = ref(false);const showLoading = () => {show.value = true;document.body.style.overflow = "hidden";document.addEventListener("touchmove", () => {}, true);
};
const hideLoading = () => {show.value = false;var mo = function (e) {e.preventDefault();};document.body.style.overflow = "";document.removeEventListener("touchmove", mo, true);
};onMounted(() => {});defineExpose({show,showLoading,hideLoading,
});
</script><style scoped>
.loading-container {position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 9999;background-color: rgba(255, 255, 255, .9);
}
.tips {font-family: "Open Sans";color: #52b852;font-size: 1rem;width: 100%;text-align: center;position: absolute;top: 55%;line-height: 30px;
}
.loader {width: 40px;aspect-ratio: 0.577;clip-path: polygon(0 0, 100% 100%, 0 100%, 100% 0);position: relative;animation: l19 2s infinite linear;overflow: hidden;position: relative;left: 50%;top: 45%;margin: 0 0 0 -25px;
}
.loader:before {content: "";position: absolute;inset: -150% -150%;background: repeating-conic-gradient(from 30deg,#ffabab 0 60deg,#abe4ff 0 120deg,#ff7373 0 180deg);animation: inherit;animation-direction: reverse;
}
@keyframes l19 {100% {transform: rotate(360deg);}
}
</style>
新建loading.js文件

index.vue的同级目录中新建loading.js文件来创建自定义指令

import {createVNode, render, cloneVNode} from "vue"
import Loading from "./index.vue"export default {install(app) {// 使用vue底层的createVNode方法将组件渲染为虚拟节点const VNode = createVNode(Loading)// 使用render函数将组件挂载到body中render(VNode, document.body)// 定义全局方法设置组件的显示和隐藏app.config.globalProperties.$showLoading = VNode.component?.exposed.showLoadingapp.config.globalProperties.$hideLoading = VNode.component?.exposed.hideLoadingconst weakMap = new WeakMap()// 自定义Loading指令app.directive("sy-loading", {mounted(el) {if (weakMap.get(el)) return//  记录当前绑定元素的positionweakMap.set(el, window.getComputedStyle(el).position)},updated(el, binding) {const oldPosition = weakMap.get(el);// 如果不是position: relative或者absolute,就设置为relative// 这里的目的是确保loading组件正确覆盖当前绑定的元素if (oldPosition !== 'absolute' && oldPosition !== 'relative') {el.style.position = 'relative'}// 克隆一份loading元素,// 作用是当页面上有多个zx-loading时,每个dom都维护一份属于自己的loading,不会冲突const newVNode = cloneVNode(VNode)// 挂载当前节点render(newVNode, el)// 判断绑定的值if (binding.value) {newVNode.component?.exposed.showLoading()} else {newVNode.component?.exposed.hideLoading(() => {// 还原布局方式el.style.position = oldPosition})}}})}
}

1. loading.ts

TS写法。上面是js写法,选其中一种即可

import type {App, VNode,} from "vue"
import {createVNode, render, cloneVNode} from "vue"
import Loading from "./index.vue"export default {install(app: App) {// 使用vue底层的createVNode方法将组件渲染为虚拟节点const VNode: VNode = createVNode(Loading )// 使用render函数将组件挂载到body中render(VNode, document.body)// 定义全局方法设置组件的显示和隐藏app.config.globalProperties.$showLoading = VNode.component?.exposed.showLoadingapp.config.globalProperties.$hideLoading = VNode.component?.exposed.hideLoadingconst weakMap = new WeakMap()// 自定义Loading指令app.directive("sy-loading", {mounted(el) {if (weakMap.get(el)) return//  记录当前绑定元素的positionweakMap.set(el, window.getComputedStyle(el).position)},updated(el: HTMLElement, binding: { value: Boolean }) {const oldPosition = weakMap.get(el);// 如果不是position: relative或者absolute,就设置为relative// 这里的目的是确保loading组件正确覆盖当前绑定的元素if (oldPosition !== 'absolute' && oldPosition !== 'relative') {el.style.position = 'relative'}// 克隆一份loading元素,// 作用是当页面上有多个zx-loading时,每个dom都维护一份属于自己的loading,不会冲突const newVNode = cloneVNode(VNode)// 挂载当前节点render(newVNode, el)// 判断绑定的值if (binding.value) {newVNode.component?.exposed.showLoading()} else {newVNode.component?.exposed.hideLoading(() => {// 还原布局方式el.style.position = oldPosition})}}})}
}
main.js引入

main.js中引入loading.js文件。

import Loading from '@/components/loading/Loading.js'
app.use(Loading)
在组件中使用
 v-sy-loading="fullscreenLoading"

在任意组件中的任意标签元素中添加v-sy-loading指定,并设置一个boolean值的参数,即可控制页面的loading加载效果

End

通过本文的介绍,我们详细探讨了如何在Vue 3中利用自定义指令来实现灵活且可复用的Loading加载效果。这一功能不仅优化了用户与应用程序之间的交互体验,还使得加载状态的显示更加直观和易于管理。我们介绍了自定义指令的基本概念、创建过程以及如何在Vue模板中优雅地应用该指令。希望这些内容能帮助你在Vue 3项目中更好地实现Loading加载效果,提升用户体验。未来,随着Vue.js的不断发展和完善,我们期待有更多创新的方法来优化用户界面的交互效果。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【循环程序设计-谭浩强适配】(适合专升本、考研)

无偿分享学习资料&#xff0c;需要的小伙伴评论区或私信dd。。。 无偿分享学习资料&#xff0c;需要的小伙伴评论区或私信dd。。。 无偿分享学习资料&#xff0c;需要的小伙伴评论区或私信dd。。。 完整资料如下&#xff1a;纯干货、纯干货、纯干货&#xff01;&#xff01;…

浅谈电动汽车充电站的电气安全

1 引言 1月14日日上午10点左右&#xff0c;青岛市市北区辽宁路63号公交停车场内&#xff0c;一辆报废公交车突然起火&#xff0c;由于大风天气&#xff0c;大火很快引燃了停在旁边的几辆报废车。消防人员快速赶到&#xff0c;迅速控制住火势。11时30分&#xff0c;停车场内的…

鸿蒙内核源码分析(ELF格式篇) | 应用程序入口并不是main

阅读之前的说明 先说明&#xff0c;本篇很长&#xff0c;也很枯燥&#xff0c;若不是绝对的技术偏执狂是看不下去的.将通过一段简单代码去跟踪编译成ELF格式后的内容.看看ELF究竟长了怎样的一副花花肠子&#xff0c;用readelf命令去窥视ELF的全貌&#xff0c;最后用objdump命令…

Image to Music V2 :只需上传一张照片,自动转换成与图片内容匹配的音频!

前言 我们之前肯定已经见过了很多文本生成图片、文本生成声音以及AI翻唱歌曲 等多种AI产品&#xff08;模型&#xff09;。 其实音乐和图片从某种意义上来说都是艺术创作的一种形式&#xff0c;它们可以相互配合&#xff0c;共同呈现出一种更加丰富、感性的表达方式。 将图片…

弘君资本:人形机器人概念走强,盛通股份涨停,怡合达、鼎智科技等拉升

人形机器人概念14日盘中拉升走高&#xff0c;到发稿&#xff0c;盛通股份涨停&#xff0c;怡合达、鼎智科技涨约6%&#xff0c;索辰科技、伟创电气、丰立智能等涨超4%。 音讯面上&#xff0c;5月13日&#xff0c;宇树发布人形智能体Unitree G1&#xff0c;身高127cm,体重35kg&…

618值得入手的数码产品怎么选?2024 买过不后悔的数码好物分享

在数字时代的浪潮中&#xff0c;每一次的购物狂欢节都如同一场科技盛宴&#xff0c;让我们有机会接触到最前沿、最实用的数码产品&#xff0c;而“618”无疑是这场盛宴中最为引人瞩目的日子之一。面对琳琅满目的商品&#xff0c;如何选择那些真正值得入手的数码好物&#xff0c…

易宝OA-ExecuteQueryForDataSetBinary处sql注入

免责声明&#xff1a; 本文内容为学习笔记分享&#xff0c;仅供技术学习参考&#xff0c;请勿用作违法用途&#xff0c;任何个人和组织利用此文所提供的信息而造成的直接或间接后果和损失&#xff0c;均由使用者本人负责&#xff0c;与作者无关&#xff01;&#xff01;&#…

Centos 安装jenkins 多分支流水线部署前后端项目

1、安装jenkins 1.1 安装jdk 要求&#xff1a;11及以上版本 yum install yum install java-11-openjdk 1.2 安装jenkins 导入镜像 sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo出现以下错误 执行以下命令 sudo yum …

使用java远程提交flink任务到yarn集群

使用java远程提交flink任务到yarn集群 背景 由于业务需要&#xff0c;使用命令行的方式提交flink任务比较麻烦&#xff0c;要么将后端任务部署到大数据集群&#xff0c;要么弄一个提交机&#xff0c;感觉都不是很离线。经过一些调研&#xff0c;发现可以实现远程的任务发布。…

LOTO示波器软件PC缓存(波形录制与回放)功能

当打开PC缓存功能后, 软件将采用先进先出的原则排队对示波器采集的每一帧数据, 进行帧缓存。 当发现屏幕中有感兴趣的波形掠过时, 鼠标点击软件的(暂停)按钮, 可以选择回看某一帧的波形。一帧数据的量 是 当前用户选择时基档位缓冲区总数据大小。不同时基档位缓冲区大小不同&am…

强化学习——马尔可夫过程的理解

目录 一、马尔可夫过程1.随机过程2.马尔可夫性质3.马尔可夫过程4.马尔可夫过程示例 参考文献 一、马尔可夫过程 1.随机过程 随机过程是概率论的“动态”版本。普通概率论研究的是固定不变的随机现象&#xff0c;而随机过程则专注于那些随时间不断变化的情况&#xff0c;比如天…

R语言两种方法实现随机分层抽样

为了减少数据分布的不平衡&#xff0c;提供高样本的代表性&#xff0c;可将数据按特征分层一定的层次&#xff0c;在每个层次抽取一定量的样本&#xff0c;为分层抽样。分层抽样的特点是将科学分组法与抽样法结合在一起&#xff0c;分组减小了各抽样层变异性的影响&#xff0c;…

C语言指针详解(三)

目录 前言 一. 回调函数是什么&#xff1f; 1.定义 2. 代码示例&#xff1a;计数器 2.1 使用回调函数改造前 2.2 使用回调函数改造后 二. qsort使用举例 1. qsort介绍 2. 使用qsort函数排序整型数据 3. 使用qsort排序结构体数据 三. qsort函数的模拟实现 四. sizeo…

代码随想录:螺旋矩阵II相关题目推荐(54、LCR146)

59.螺旋矩阵II 题目 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5]] 代码&#xff08;新解法&am…

MyBatis——MyBatis 参数处理

一、单个简单类型参数 简单类型包括&#xff1a; byte short int long float double char Byte Short Integer Long Float Double Character String java.util.Date java.sql.Date parameterType 属性&#xff1a;告诉 MyBatis 参数的类型 MyBatis 自带类型自动推断机制…

LLM应用-prompt提示:生成搜索相关问题、生成回答格式包含参考资料

参考: https://isou.chat/ (AI回答与相关问题都是根据问题的搜索引擎结果结合大模型生成的) prompt参考: https://github.com/yokingma/search_with_ai/blob/6d32aa8f05f5f6ee12b5204787035b3f7797c22a/src/prompt.ts#L8 ##rag 根据搜索结果知识回答RagQueryPrompt = ` …

程控水冷阻性负载主要工作方式

程控水冷阻性负载是一种先进的电力设备&#xff0c;主要用于电力系统的测试和研究。它的主要工作方式是通过控制水冷系统的温度&#xff0c;来模拟不同的阻性负载条件&#xff0c;从而对电力设备进行各种性能测试。 首先&#xff0c;我们需要了解什么是阻性负载。阻性负载是指那…

代码随想录算法训练营Day 42| 动态规划part04 | 01背包问题理论基础I、01背包问题理论基础II、416. 分割等和子集

代码随想录算法训练营Day 42| 动态规划part04 | 01背包问题理论基础I、01背包问题理论基础II、416. 分割等和子集 文章目录 代码随想录算法训练营Day 42| 动态规划part04 | 01背包问题理论基础I、01背包问题理论基础II、416. 分割等和子集01背包问题理论基础一、01背包问题二、…

Redis教程——哨兵

在上篇文章我们学习了Redis教程——主从复制&#xff0c;这篇文章我们学习Redis教程——哨兵监控。 在主从复制中如果主机发生宕机&#xff0c;从机Redis会一直等到主机的恢复&#xff0c;这样会导致只能进行读操作&#xff0c;不能进行写操作&#xff0c;这大大降低了系统的高…

资料同化 | 搭建docker环境-1

Community Gridpoint Statistical Interpolation (GSI) system DTC 是一个分布式设施&#xff0c;NWP 社区可以在这里测试和评估用于研究和操作的新模型和技术。 DTC的目标包括&#xff1a; 链接研究和操作社区 研究成果转化为实际操作的速度 加快改善天气预报 开发和测试有…