Vue + AbortController 請求取消彈窗 hook 封裝

背景

實際業務開發場景中,往往存在有些大數據請求的需求,一旦請求發起加載遮罩后用戶就無法操作了,直接尬住,所以提供一個支持取消查詢的功能還是很有必要的,為了在全業務接口都能使用封裝一個hook。

?為什么要用 AbortController?

AbortController 是瀏覽器提供的原生 API,用于中止 Web 請求(如 Fetch)。你可以通過調用 abort() 來通知一個綁定了該信號(signal)的請求停止執行。

簡單來說,它的用法是這樣的:

const controller = new AbortController();
const signal = controller.signal;fetch('/api/slow-request', { signal }).catch(err => {if (err.name === 'AbortError') {console.log('請求被中止了');}
});setTimeout(() => {controller.abort(); // 中止請求
}, 2000);

這在 Vue 中也完全適用,尤其是你使用 Axios、Fetch 或其他支持 AbortSignal 的封裝庫時。

🧠 思考:hook設計需解決的問題?

  • 啟動查詢時,展示一個 loading 動畫。

  • 2 秒后仍未返回結果,彈出一個“取消查詢”的提示框。

  • 如果用戶點擊“取消”,則主動中止請求。

  • 請求成功或被取消后,清除提示框和 loading。

這就是我們這個 Hook 要完成的全部職責。

🏃?? 實現步驟

第一步:定義中止信號 signal

我們在 Hook 中需要一個 ref 來存儲當前的 AbortSignal,方便傳給請求調用者。

const signal = ref<AbortSignal>({} as AbortSignal);

同時,我們在每次調用前重新創建一個 AbortController,保證每次請求都能獨立控制。

第二步:啟動 loading 和延遲彈窗

當用戶點擊“查詢”按鈕后,我們要立即顯示一個 ElLoading 動畫,然后 延遲 2 秒 后再彈出取消窗口。

為什么要延遲?

很多請求會在 2 秒內返回,沒必要給用戶太多打擾。我們只在“慢”的時候,才提醒用戶可以取消。

loading = ElLoading.service({lock: true,text: '',background: 'rgba(0,0,0,0.2)',
});timer = setTimeout(() => {ElMessageBox.confirm('<div class="flex flex-col gap-3 items-center"><div class="w-10 h-10 border-4 border-t-blue-500 border-gray-300 rounded-full animate-spin"></div><p>查詢中...</p></div>','提示',{dangerouslyUseHTMLString: true,customClass: 'custom-style',showClose: false,showCancelButton: false,confirmButtonText: '取消查詢',closeOnClickModal: false,closeOnPressEscape: false,},).then(() => {// 中止請求controller.abort();// 中止 后端真實請求查詢stopTrueRequest().then(() => {ElMessage.success('已取消查詢!');});});}, 2000);

這個 MessageBox 是關鍵,它展示了一個動畫+提示文字,并提供“取消查詢”的按鈕。當點擊時,我們會執行:

controller.abort();

中止請求,取消回調里可以調用真實取消查詢的接口。

第三步:清理 timer 和 loading

無論請求成功還是被取消,我們都要記得清理 timer 和 loading:

const cancelPendingAlert = () => {loading?.close();if (timer) {clearTimeout(timer);timer = null;}
};
// 卸載時也要清理
onUnmounted(() => {if (timer) clearTimeout(timer);if (loading) loading.close();
});

最終 Hook 導出結構

return {loadCancelAlert,cancelPendingAlert,signal,
};

🚀 如何在頁面中調用?

我們在業務組件中使用這個 Hook 時,可以這樣寫:

const { loadCancelAlert, cancelPendingAlert, signal } = useCancelRequest();const testCancel = () => {loadCancelAlert(); // 顯示 loading & 準備彈窗testCancelApi('', signal.value).then(() => {cancelPendingAlert();}).finally(() => {cancelPendingAlert(); // 兜底關閉ElMessageBox.close(); // 主動關閉提示框});
};

注意這里的 testCancelApi 是你封裝的接口請求函數,它需要支持接收 signal:

export function testCancelApi<T>(data: string, signal: AbortSignal) {return request<T>({url: '/api/v1/test',method: 'POST',data,signal, // ? 添加 signal 支持中斷});
}

最終效果

界面
在這里插入圖片描述
實際請求
在這里插入圖片描述

hook 完整代碼

import { ElLoading, ElMessage, ElMessageBox } from 'element-plus';
import { LoadingInstance } from 'element-plus/es/components/loading/src/loading';
import { onUnmounted, ref } from 'vue';export default function useCancelRequest() {const signal = ref<AbortSignal>({} as AbortSignal); // 終止標識let timer: ReturnType<typeof setTimeout> | null = null; // 定時器延遲彈窗加載let loading: LoadingInstance;/** 初始化取消請求彈窗 */const loadCancelAlert = () => {const controller = new AbortController(); // 請求終止器signal.value = controller.signal;loading = ElLoading.service({lock: true,text: '',background: 'rgab(0,0,0,0.2)',});timer = setTimeout(() => {ElMessageBox.confirm('<div class="flex flex-col gap-3 items-center"><div class="w-10 h-10 border-4 border-t-blue-500 border-gray-300 rounded-full animate-spin"></div><p>查詢中...</p></div>','提示',{dangerouslyUseHTMLString: true,customClass: 'custom-style',showClose: false,showCancelButton: false,confirmButtonText: '取消查詢',closeOnClickModal: false,closeOnPressEscape: false,},).then(() => {// 中止請求controller.abort();// 中止 后端真實請求查詢stopTrueRequest().then(() => {ElMessage.success('已取消查詢!');});});}, 2000);};// 請求完成時調用,取消加載取消請求彈窗const cancelPendingAlert = () => {loading?.close();if (timer) {clearTimeout(timer);timer = null;}};onUnmounted(() => {if (timer) clearTimeout(timer);if (loading) loading.close();});return {loadCancelAlert,cancelPendingAlert,signal,};
}

完結撒花🎉🎉🎉
歡迎點贊+收藏+關注😀

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/85566.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/85566.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/85566.shtml

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

相關文章

數據結構相關

1 問題 如何辨析數據對象和數據結構&#xff1f;如何設計多種儲存結構以及他們特性有什么&#xff1f;內存條和硬盤的區別&#xff1f; 2 方法 明晰倆者的定義數據對象是性質相同的有限個數據元素的集合&#xff0c;他是數據的一個子集。數據結構是指所涉及的數據元素的集合以及…

MacOS內存管理-刪除冗余系統數據System Data

文章目錄 一、問題復現二、解決思路三、解決流程四、附錄 一、問題復現 以題主的的 Mac 為例&#xff0c;我們可以看到System Data所占數據高達77.08GB&#xff0c;遠遠超出系統所占內存 二、解決思路 占據大量空間的是分散在系統中各個位置Cache數據&#xff1b; 其中容量最…

純視覺SOTA!華科小米推出ReCogDrive:結合VLM和強化學習的端到端自動駕駛框架

摘要 端到端自動駕駛的研究目前越來越火熱&#xff0c;現有方法通過視覺語言模型&#xff08;VLM&#xff09;來解決其在長尾場景中性能降低的問題&#xff0c;但是仍然存在一些局限性。本文提出了ReCogDrive&#xff0c;它將VLM與基于擴散的軌跡規劃器相結合&#xff0c;并且采…

MySQL慢SQL優化全攻略:從診斷到調優

目錄 慢SQL日志分析與診斷 開啟慢查詢日志 慢查詢日志分析工具 慢SQL優化策略 1. 避免SELECT * 查詢 2. 創建高效索引 索引選擇原則 索引使用注意事項 3. 使用EXPLAIN分析執行計劃 4. 優化排序操作 5. 解決深分頁問題 6. 避免全表掃描 7. 優化JOIN操作 8. 合理使用…

OPENPPP2 VMUX 技術探秘(高級指南)

&#x1f680; VMUX技術分析&#xff1a;OPENPPP2中的虛擬多路復用技術 &#x1f31f; 一、技術目標 &#x1f517; 連接多路復用 通過單個或多個物理鏈路&#xff0c;承載多個邏輯TCP連接。 &#x1f680; 高性能傳輸 支持數據包亂序重組實現動態流量控制&#xff08;擁塞檢測…

Linux系統時間不對導致mysql初始化失敗:Data Dictionary initialization failed.(數據字典版本驗證失敗)

文章目錄 問題描述分析**問題原因分析****解決方案****1. 修正系統時間****2. 檢查數據目錄完整性****3. 重新初始化數據目錄****4. 調整 MySQL 配置** **驗證與后續步驟****注意事項** 其他說明 問題描述 mysql數據初始化失敗&#xff0c;發現系統時間是1970年&#xff0c;我…

有趣的python程序Part1:如何根據記憶曲線使用python編寫一個單詞記憶默寫程序

目錄 前言 1. 數據管理模塊 2. 記憶算法實現 3. 持久化存儲 4. 用戶界面實現 5.整合與測試 前言 此篇文章為“有趣的python程序”專欄的第一篇文章&#xff0c;本專欄致力于分享一些有趣的編程作品&#xff0c;如果能夠使您產生興趣&#xff0c;不妨來動手改編使之成為更好…

【案例】性能優化在持續集成與持續交付中的應用

【案例】性能優化在持續集成與持續交付中的應用 為了更好地理解性能優化在CI/CD流程中的實際應用&#xff0c;本節將結合一個典型案例&#xff0c;從代碼提交到部署上線的完整流程中&#xff0c;講解如何嵌入性能檢測與自動化優化機制&#xff0c;并使用結構化流程圖直觀展示關…

P7 QT項目----會學天氣預報(完結)

7.8 QMap 在 Qt 中&#xff0c;如果你想要將 JSON 數據解析到一個 QMap 中&#xff0c;你可以遍歷 JSON 對象的所有鍵值對&#xff0c;并將它們添加到 QMap 里。這個方法特別適合于當你的 JSON 對象是一個簡單的鍵值對集合時。以下是一個如何實現這一點的示例。 示例&#…

操作系統筆記(關于進程引入和狀態的切換)

1.前言 今天下午結束了英語的四六級考試&#xff0c;終于是結束了&#xff0c;最近的這個考試太密集&#xff0c;周四的專業基礎課考試&#xff0c;周五的這個線性代數的考試和這個周六的英語四六級考試&#xff0c;吧我都要烤焦了&#xff0c;最近也是疲于應對這個考試&#…

M1芯片macOS安裝Xinference部署大模型

如果你看的是官方手冊&#xff1a;安裝 — Xinference 千萬不要直接運行&#xff1a; pip install "xinference[all]" 會遇到幾個問題&#xff1a; 1&#xff09;Python版本如果太新可能安裝失敗 2&#xff09;全量安裝會失敗 3&#xff09;未科學上網可能會time…

【ONNX量化實戰】使用ONNX Runtime進行靜態量化

目錄 什么是量化量化實現的原理實戰準備數據執行量化 驗證量化結語 什么是量化 量化是一種常見的深度學習技術&#xff0c;其目的在于將原始的深度神經網絡權重從高位原始位數被動態縮放至低位目標尾數。例如從FP32&#xff08;32位浮點&#xff09;量化值INT8&#xff08;8位…

【量子計算】格羅弗算法

文章目錄 &#x1f50d; 一、算法原理與工作機制? 二、性能優勢&#xff1a;二次加速的體現&#x1f310; 三、應用場景?? 四、局限性與挑戰&#x1f52e; 五、未來展望&#x1f48e; 總結 格羅弗算法&#xff08;Grover’s algorithm&#xff09;是量子計算領域的核心算法之…

C++ 互斥量

在 C 中&#xff0c;互斥量&#xff08;std::mutex&#xff09;是一種用于多線程編程中保護共享資源的機制&#xff0c;防止多個線程同時訪問某個資源&#xff0c;從而避免數據競爭&#xff08;data race&#xff09;和不一致的問題。 &#x1f512; 一、基礎用法&#xff1a;s…

CSS Content符號編碼大全

資源寶整理分享&#xff1a;?https://www.httple.net? 前端開發中常用的特殊符號查詢工具&#xff0c;包含Unicode編碼和HTML實體編碼&#xff0c;方便開發者快速查找和使用各種符號。支持基本形狀、箭頭、數學符號、貨幣符號等多種分類。 前端最常用符號 圖標形狀十進制十…

RPC常見問題回答

項目流程和架構設計 1.服務端的功能&#xff1a; 1.提供rpc調用對應的函數 2.完成服務注冊 服務發現 上線/下線通知 3.提供主題的操作 (創建/刪除/訂閱/取消訂閱) 消息的發布 2.服務的模塊劃分 1.網絡通信模塊 net 底層套用的moude庫 2.應用層通信協議模塊 1.序列化 反序列化數…

【JavaEE】(3) 多線程2

一、常見的鎖策略 1、樂觀鎖和悲觀鎖 悲觀鎖&#xff1a;預測鎖沖突的概率較高。在鎖中加阻塞操作。樂觀鎖&#xff1a;預測鎖沖突的概率較低。使用忙等/版本號等&#xff0c;不產生阻塞。 2、輕量級鎖和重量級鎖 重量級鎖&#xff1a;加鎖的開銷較大&#xff0c;線程等待鎖…

創客匠人服務體系解析:知識 IP 變現的全鏈路賦能模型

在知識服務行業深度轉型期&#xff0c;創客匠人通過 “工具 陪跑 圈層” 的三維服務體系&#xff0c;構建了從 IP 定位到商業變現的完整賦能鏈條。這套經過 5 萬 知識博主驗證的模型&#xff0c;不僅解決了 “內容生產 - 流量獲取 - 用戶轉化” 的實操難題&#xff0c;更推動…

國產ARM/RISCV與OpenHarmony物聯網項目(六)SF1節點開發

一、終端節點功能設計 1. 功能說明 終端節點設計的是基于鴻蒙操作系統的 TCP 服務器程序&#xff0c;用于監測空氣質量并提供遠程控制功能。與之前的光照監測程序相比&#xff0c;這個程序使用 E53_SF1 模塊&#xff08;煙霧 / 氣體傳感器&#xff09;&#xff0c;主要功能包…

Plotly圖表全面使用指南 -- Displaying Figures in Python

文中內容僅限技術學習與代碼實踐參考&#xff0c;市場存在不確定性&#xff0c;技術分析需謹慎驗證&#xff0c;不構成任何投資建議。 在 Python 中顯示圖形 使用 Plotly 的 Python 圖形庫顯示圖形。 顯示圖形 Plotly的Python圖形庫plotly.py提供了多種顯示圖形的選項和方法…