這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 在我們寫項目代碼時,應該更加專註於業務邏輯的實現,而把定式代碼交給js庫或工程化自動處理,而我想說的是,請求邏輯其實也是可以繼續簡化的。 你可能會說,用axios或fetch api就夠了啊,哪有什麼請求邏輯,那可能是你還沒有意識到這個問 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
在我們寫項目代碼時,應該更加專註於業務邏輯的實現,而把定式代碼交給js庫或工程化自動處理,而我想說的是,請求邏輯其實也是可以繼續簡化的。
你可能會說,用axios或fetch api就夠了啊,哪有什麼請求邏輯,那可能是你還沒有意識到這個問題,作為一個前端開發,你肯定也遇到過這些問題:
- 處理分頁邏輯
- 表單處理邏輯
- 處理請求防抖邏輯
- 處理輪詢檢查
- 處理緩存處理
- 處理載入狀態
- 處理錯誤處理
- 驗證碼發送
- 文件上傳
- ...
這些問題,如果你正在使用 axios 或 fetch api,你需要編寫大量的代碼來處理這些問題,但我想說,他們其實更多的也都是固定的模板代碼,也可以被精簡掉。
在今天你可以使用 alova 來處理它們,alova提供了大量日常業務中常用的請求模塊,你只需要簡單配置幾行代碼,alova 就能自動幫你管理請求狀態,優化網路體驗,那些煩人的分頁邏輯、輪詢檢查、緩存處理,全都不用你操心了,讓你更加專註於業務邏輯。
alova的學習成本更低
alova 借鑒了 axios 和ahooks-useRequest的設計,讓大家更容易上手,學習成本更低。
alova 官網在這裡。
alova 自從 2023 年 4 月份正式對外發佈以來,在 Issues 和 Disscussion 中收到了來自世界各地的開發者積极參与的信息,深感榮幸。
如果你也喜歡 alovajs,請在Github 倉庫中貢獻一顆 star,這對我們非常重要。
有任何問題,你可以加入以下群聊咨詢,也可以在github 倉庫中發佈 Discussions,如果遇到問題,也請在github 的 issues中提交,我們會在最快的時間解決。
下麵我們來看看如何通過簡單配置,就能幫你解決各種複雜場景下的請求問題。
基礎請求
基本的請求,適用於初始化信息,自帶了請求相關的各種狀態。
以 vue3 為例。
<template> <div> <div v-if="loading">loading...</div> <div v-else-if="error">error: {{ error }}</div> <div v-else> <div> <span>id: {{ data.title }}</span> <span>title: {{ data.time }}</span> </div> </div> </div> </template> <script setup> import { useRequest } from "alova"; // 和axios相似的參數風格 const todoDetail = alova.Get("/todo", { params: { id: 1, }, }); const { loading, data, error, onSuccess, onError, onComplete, send, abort, update, } = useRequest(todoDetail); onSuccess((event) => { console.log("success", event); }); onError((event) => { console.log("error", event); }); onComplete((event) => { console.log("complete", event); }); </script>
useRequest 會自動幫你管理 loading、data、error 等狀態,不需要自己控制!
狀態變化請求
在數據篩選、搜索等交互中,可以通過 useWatcher 來監聽狀態變化併發送請求,返回值也包含與 useRequest 相同的狀態、事件函數、操作函數。
useWatcher(() => filterTodoList(page, keyword), [keyword, page], { debounce: [500, 0], // 請求級的防抖參數 });
它還有請求防抖、保證請求時序、過濾狀態變化時是否發送請求等功能,超方便!
預載入數據
可以用 useFetcher 預載入數據,不需要直接處理響應,但會更新相關狀態:
const { fetching, error, fetch } = useFetcher(); fetch(todoDetail);
分頁請求
分頁場景下,page、pageSize、pageCount、total 等等好多狀態要自己維護,還要寫一堆邏輯來判斷何時應該發送請求!
如果用 alovajs 提供的分頁 Hook,你就只需要這樣:
const { // 載入狀態 loading, // 列表數據 data, // 是否為最後一頁 // 下拉載入時可通過此參數判斷是否還需要載入 isLastPage, // 當前頁碼,改變此頁碼將自動觸發請求 page, // 每頁數據條數 pageSize, // 分頁頁數 pageCount, // 總數據量 total, } = usePagination((page, pageSize) => queryStudents(page, pageSize)); // 翻到上一頁,page值更改後將自動發送請求 const handlePrevPage = () => { page.value--; }; // 翻到下一頁,page值更改後將自動發送請求 const handleNextPage = () => { page.value++; }; // 更改每頁數量,pageSize值更改後將自動發送請求 const handleSetPageSize = () => { pageSize.value = 20; };
是不是清爽很多,節省了超多重覆代碼。
表單提交
表單處理也很頭疼吧?alova 的 useForm 直接幫你搞定表單提交、表單草稿、自動重置表單項、多頁共用數據啥的。
const { form, send: submitForm, updateForm, } = useForm((formData) => submitData(formData), { initialForm: { title: "", content: "", time: "", }, resetAfterSubmiting: true, });
驗證碼實現
別再自己做倒計時了,這有!
const { loading: sending, send: sendCaptcha } = useCaptcha( () => sendCaptcha(mobile), { initialCountdown: 60, } );
文件上傳策略
更簡單的文件上傳策略,支持對 base64、Blob、ArrayBuffer、Canvas 數據的自動識別和轉換,還可以多文件同時上傳、圖片預覽圖生成
const { fileList loading, progress } = useUploader(({ file, name }) => uploadFile(file, name), { limit: 3, accept: ['png', 'jpg', 'gif'], imageTempLink: true });
自動重新拉取數據
可以在瀏覽器 tab 切換時拉取最新數據、瀏覽器聚焦時拉取最新數據、網路重連時拉取最新數據、輪詢請求自動重新拉取數據,可以同時配置以上的一個或多個觸發條件,也可以配置節流時間來防止短時間內觸發多次請求,例如 1 秒內只允許觸發一次。
useAutoRequest(todoDetail, { enablePolling: 2000, enableVisibility: true, enableFocus: true, enableNetwork: true, throttle: 1000 }
跨組件請求策略
跨組件或模塊觸發請求相關操作,消除組件層級的限制,在任意組件中快速地觸發任意請求的操作函數,例如,你可以某個組件中更新了菜單數據後,重新觸發側邊菜單欄的重新請求,從而刷新數據。當操作了列表數據後,觸發列表更新。
// 組件A創建代理 useRequest(todoDetail, { middleware: actionDelegationMiddleware("someAction"), }); // 組件B內觸發操作 accessAction("someAction", (actions) => { actions.send(); });
actionDelegationMiddleware 詳細文檔
請求重試策略
在重要的請求上使用它,可以提高請求的穩定性,可以自定義設置是否重試,以及重試延遲,還有手動停止重試
const { onRetry, onFail, stop } = useRetriableRequest(pay, { retry(error) { return /network timeout/i.test(error.message); }, backoff: { delay: 2000, }, });
SSE
可以直接通過 SSE 進行請求,它可以通過全局響應和方法實例的函數 transformData 自動轉換數據,還提供了對 EventSource 對象的全部控制。
const { readyState, data, eventSource, onMessage, onError, onOpen, on } = useSSE(() => chatGPT(), { withCredentials: true, interceptByGlobalResponded: true, });