
上一篇說過列表頁的“忙”不是一個是幾個。這一篇把這些“忙”落成三層每一層有自己的歸屬和關門條件。分層以后交給 Codex 的任務就從“加個 loading”變成“給這個頁面找出幾個等待每個等待歸誰管”。分層不是命名游戲。真正的依據是生命周期誰觸發的、等誰的、誰有權結束。頁面級遮罩只認首屏不認每一次請求頁面級的等待起點是頁面掛載終點是首屏數據就緒。它的作用是把整頁空白擋在后面遮罩一關頁面就進入可用狀態。這一層最容易寫錯的地方是讓它跟著后續每一次翻頁、查詢開開關關。首屏過后再查一遍數據頁面本身不需要重新遮罩遮罩反復出現反而打斷操作。結構示意const firstLoad ref(true); const list ref([]); ? const initList async () { firstLoad.value true; try { list.value await listApi({ page: 1, size: 10 }); } finally { firstLoad.value false; } };finally只是確保這個狀態一定會復位不代表它解決了并發。首屏和翻頁如果共用同一個請求入口還需要請求資格判斷這一點上一篇已經拆過。按鈕級節流和去重是兩件事按鈕級的等待屬于一次提交起點是點擊終點是這次提交的響應。它要解決的是用戶手快連點兩次。const saving ref(false); ? const onSave async (form) { if (saving.value) return; saving.value true; try { await saveApi(form); } finally { saving.value false; } };這里擋住的只是“同一時間只發一次”。還有一類問題它擋不住請求已經發出、響應也回來了用戶刷新頁面或后退后再點一次同一份表單又提交了一份。那是冪等和去重的事不是節流的事。web-skills把按鈕節流交給btnState配置在請求攔截器里打開、響應或異常里關閉。它管的是節流這一段不負責業務冪等。給 Codex 描述按鈕狀態時要先分清這次要解決的是連點還是重復數據兩個目標對應兩套機制。局部級表格區域和彈框各自關門局部級的等待發生在頁面已經可用之后只影響一小塊區域。典型的是表格查詢和彈框內加載。const listLoading ref(false); const dialogLoading ref(false); ? const loadList async (params) { listLoading.value true; try { return await listApi(params); } finally { listLoading.value false; } };表格的listLoading只跟隨列表請求彈框的dialogLoading只跟隨彈框請求。它們不該互相覆蓋也不該去動頁面級的遮罩。web-skills用loading和dialogLoading兩個獨立配置項把這兩段分開。目標項目若沒有這套封裝至少要保證一個區域的狀態不會因為另一個區域的請求結束而被關掉。局部級還有一個并發細節。兩次翻頁快速切換時第一次請求后返回也會執行finally把listLoading提前關掉。所以局部狀態同樣要配請求資格判斷否則分層了遮罩還是會被舊響應提前收走。三層之間的關閉條件先寫清楚再讓 Codex 動手層級觸發者關閉條件常見錯寫頁面級頁面掛載首屏數據 settle跟隨每次查詢反復遮罩按鈕級用戶點擊本次提交 settle用全局 loading 代替按鈕狀態局部級區域請求該區域最新請求 settle被其它區域或舊響應關閉這張表交給 Codex 之前先確認“settle”在項目里的含義。有的團隊只要請求返回就關有的要求數據已寫入狀態再關。口徑不統一分層再清楚也會在交接處出縫。分層后的驗收一半靠讀代碼一半靠跑頁面加載狀態沒法只靠靜態審查交付有一部分必須打開頁面才能確認。靜態能查的每個 loading 狀態有沒有獨立的來源關閉發生在響應成功、失敗還是finally有沒有哪個狀態被多個請求共用。要跑頁面的并發翻頁時遮罩會不會被舊響應提前關掉保存期間表格查詢的 loading 是否被誤關首屏遮罩關掉后表格是否已就緒。這些需要一次真實操作或者明確記為未驗證不能靠讀代碼下結論。交給 Codex 的任務模板請為這張列表頁整理加載狀態不先改代碼 ? 1. 列出頁面里所有“忙”的場景首屏、翻頁、查詢、刷新、保存、彈框加載等。 2. 為每個場景標出層級頁面級、按鈕級還是局部級。 3. 記錄每個狀態當前由誰寫入、在哪個請求或生命周期里關閉。 4. 找出被兩個以上請求共用的狀態說明誰先返回會影響誰。 5. 區分按鈕節流和業務冪等指出本項目當前只解決了哪個。 ? 先給出分層表和關閉條件再給最小修改方案。不要新增一個統一 loading 把現有狀態包起來也不要繞開項目已有的請求封裝。這條任務的第一句就是“不先改代碼”。加載狀態的混亂大多是因為動手之前沒人把“幾個忙、各歸誰”數清楚。數清楚了改哪里通常是顯而易見的。寫在最后分層解決的不是命名問題是關門權。頁面遮罩、按鈕狀態、區域加載各有各的生命周期把它們塞進一個布爾值遮罩就會在錯誤的時間消失。按頁面、按鈕、局部三層劃清歸屬和關閉條件再配合請求資格判斷加載狀態才從“加了個變量”變成“每條等待都有出處”。下一篇進到按鈕這一層專門講重復提交連點、雙擊、提交后刷新、接口重試分別該用節流、去重還是冪等來擋而不是一律塞進btnState。本系列持續更新。列表頁的加載和提交狀態收束后會回到頁面異常路徑看接口失敗時列表應該如何退化。參考資料OpenAI Codex 用例理解代碼庫中的請求流、模塊職責與隱藏依賴