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.pswp.cn/web/11861.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11861.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11861.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flet初體驗:Python跨平臺開發新選擇

文章目錄 ?? 介紹 ???? 演示環境 ???? 初識Flet ???? 安裝與配置?? 構建第一個Flet應用?? Flet打包:跨平臺的魔法?? Flet與FastAPI的結合?? 總結?? 相關鏈接 ???? 介紹 ?? “探索未知,擁抱創新,Flet讓我在應用開發的世界中找到了新的航標。”…

02 | 該如何選擇消息隊列?

RabbitMQ RabbitMQ 一個比較有特色的功能是支持非常靈活的路由配置&#xff0c;和其他消息隊列不同的是&#xff0c;它在生產者&#xff08;Producer&#xff09;和隊列&#xff08;Queue&#xff09;之間增加了一個 Exchange 模塊&#xff0c;你可以理解為交換機。 問題 Ra…

【循環程序設計-譚浩強適配】(適合專升本、考研)

無償分享學習資料&#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&…

[240514] OpenAI 發布 GPT-4o,人機交互的歷史性時刻 | 蘋果芯片進軍服務器劍指AI? | 谷歌大會以AI為主

目錄 OpenAI 發布 GPT-4o&#xff0c;人機交互的歷史時刻蘋果芯片進軍服務器&#xff0c;劍指生成式 AI2024年谷歌開發者大會將圍繞 AI 展開 OpenAI 發布 GPT-4o&#xff0c;人機交互的歷史時刻 OpenAI 發布了 GPT-4o&#xff0c;大家一直都想要現在終于等到的語音助手 : 勿需…

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 …

前端使用原生JS怎么上傳本地路徑的文件到后端【附源碼】

本文不使用<input type"file">等前端上傳組件 一、為什么不能使用本地文件路徑上傳&#xff1f; 前端不能直接根據本地文件路徑&#xff08;例如 C:\Users\Username\Documents\image.jpg&#xff09;上傳文件到后端服務器&#xff0c;原因主要在于瀏覽器的安全…

使用java遠程提交flink任務到yarn集群

使用java遠程提交flink任務到yarn集群 背景 由于業務需要&#xff0c;使用命令行的方式提交flink任務比較麻煩&#xff0c;要么將后端任務部署到大數據集群&#xff0c;要么弄一個提交機&#xff0c;感覺都不是很離線。經過一些調研&#xff0c;發現可以實現遠程的任務發布。…

LOTO示波器軟件PC緩存(波形錄制與回放)功能

當打開PC緩存功能后, 軟件將采用先進先出的原則排隊對示波器采集的每一幀數據, 進行幀緩存。 當發現屏幕中有感興趣的波形掠過時, 鼠標點擊軟件的(暫停)按鈕, 可以選擇回看某一幀的波形。一幀數據的量 是 當前用戶選擇時基檔位緩沖區總數據大小。不同時基檔位緩沖區大小不同&am…

談談std::map的lower_bound

我們知道std::map內部是一個紅黑樹&#xff0c;放到std::map里的數據等有一個能比較大小的方法。它相當于java里面的TreeMap。 它里面有個lower_bound方法&#xff0c;返回一個迭代器&#xff0c;它指向map里第一個大于等于參數的元素。 方法的簽名很簡單&#xff0c;但是在不同…

富格林:有效預防黑幕阻撓被騙

富格林指出&#xff0c;在投資領域&#xff0c;現貨黃金是一種備受推崇的貴金屬投資品種。倘若能有效預防黑幕阻撓被騙的情況&#xff0c;事實上現貨黃金是很多投資者的“理想型”。然而要想有效地預防黑幕阻撓被騙&#xff0c;就需要掌握足夠多的投資技巧。為此&#xff0c;富…

Milvus 基本概念

Milvus 是一個開源的向量數據庫&#xff0c;專門用于高效地存儲、管理和檢索大規模向量數據。它基于 Apache 許可證 2.0 版本發布&#xff0c;由 Zilliz 公司開源并維護。 Milvus 的設計理念是為了解決向量數據存儲和檢索的挑戰。在許多應用中&#xff0c;向量數據是一種重要的…

強化學習——馬爾可夫過程的理解

目錄 一、馬爾可夫過程1.隨機過程2.馬爾可夫性質3.馬爾可夫過程4.馬爾可夫過程示例 參考文獻 一、馬爾可夫過程 1.隨機過程 隨機過程是概率論的“動態”版本。普通概率論研究的是固定不變的隨機現象&#xff0c;而隨機過程則專注于那些隨時間不斷變化的情況&#xff0c;比如天…

C# 使用channel 實現Plc 異步任務之間的通信

channel 通信的例子: using ConsoleApp2; using System.Collections.Concurrent; using System.Threading.Channels;var queue = new BlockingCollection<Message>(new ConcurrentQueue<Message>());var opt = new BoundedChannelOptions(10) {FullMode = BoundedC…

Linux環境快速部署mysql5.7

1 網絡下載rpm包 wget -c https://repo.huaweicloud.com/mysql/Downloads/MySQL-5.7/mysql-5.7.37-1.el7.x86_64.rpm-bundle.tar2 解壓 tar xf mysql-5.7.37-1.el7.x86_64.rpm-bundle.tar3 數據庫之間會沖突因此需要卸載mariadb-libs yum remove mariadb-libs4 安裝 如果沒有…