@melt-js/docs-bag 0.0.0-stage → 2026.11.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -2
- package/dist/404.html +22 -0
- package/dist/README.html +33 -0
- package/dist/assets/README.md.BEUJStMI.js +9 -0
- package/dist/assets/README.md.BEUJStMI.lean.js +1 -0
- package/dist/assets/app.CPZ-gtYR.js +1 -0
- package/dist/assets/chunks/@localSearchIndexroot.7ill5i5O.js +1 -0
- package/dist/assets/chunks/VPLocalSearchBox.BVA3GWxn.js +9 -0
- package/dist/assets/chunks/framework.B3lxS50j.js +20 -0
- package/dist/assets/chunks/theme.C4rSMcmz.js +2 -0
- package/dist/assets/guide_complete-host-app.md.CDRzLz0E.js +174 -0
- package/dist/assets/guide_complete-host-app.md.CDRzLz0E.lean.js +1 -0
- package/dist/assets/guide_create-project.md.LRNhDD9x.js +34 -0
- package/dist/assets/guide_create-project.md.LRNhDD9x.lean.js +1 -0
- package/dist/assets/guide_deployment.md.B8aEUabm.js +42 -0
- package/dist/assets/guide_deployment.md.B8aEUabm.lean.js +1 -0
- package/dist/assets/guide_dictionary-system.md.Dy0tQYMR.js +32 -0
- package/dist/assets/guide_dictionary-system.md.Dy0tQYMR.lean.js +1 -0
- package/dist/assets/guide_getting-started.md.B-mobXxi.js +9 -0
- package/dist/assets/guide_getting-started.md.B-mobXxi.lean.js +1 -0
- package/dist/assets/guide_host_auth-and-permissions.md.DWH3Vape.js +139 -0
- package/dist/assets/guide_host_auth-and-permissions.md.DWH3Vape.lean.js +1 -0
- package/dist/assets/guide_host_bootstrap.md.DpbxPIZw.js +87 -0
- package/dist/assets/guide_host_bootstrap.md.DpbxPIZw.lean.js +1 -0
- package/dist/assets/guide_host_routing-and-menu.md.BdCMIOxn.js +103 -0
- package/dist/assets/guide_host_routing-and-menu.md.BdCMIOxn.lean.js +1 -0
- package/dist/assets/guide_introduction.md.1MiCcWyO.js +14 -0
- package/dist/assets/guide_introduction.md.1MiCcWyO.lean.js +1 -0
- package/dist/assets/guide_local-debugging.md.CLJoKVb9.js +15 -0
- package/dist/assets/guide_local-debugging.md.CLJoKVb9.lean.js +1 -0
- package/dist/assets/guide_network-request.md.DDlA8bc0.js +256 -0
- package/dist/assets/guide_network-request.md.DDlA8bc0.lean.js +1 -0
- package/dist/assets/guide_official-plugins_index.md.DPwemCGy.js +15 -0
- package/dist/assets/guide_official-plugins_index.md.DPwemCGy.lean.js +1 -0
- package/dist/assets/guide_official-plugins_install-and-toggle.md.Eq2hWjYn.js +45 -0
- package/dist/assets/guide_official-plugins_install-and-toggle.md.Eq2hWjYn.lean.js +1 -0
- package/dist/assets/guide_official-plugins_shop.md.yBltEx-o.js +49 -0
- package/dist/assets/guide_official-plugins_shop.md.yBltEx-o.lean.js +1 -0
- package/dist/assets/guide_official-plugins_sys-setting.md.BmkuOqGv.js +26 -0
- package/dist/assets/guide_official-plugins_sys-setting.md.BmkuOqGv.lean.js +1 -0
- package/dist/assets/guide_package-core.md.-E29SYy8.js +45 -0
- package/dist/assets/guide_package-core.md.-E29SYy8.lean.js +1 -0
- package/dist/assets/guide_package-ecosystem.md.Di3RcVpF.js +1 -0
- package/dist/assets/guide_package-ecosystem.md.Di3RcVpF.lean.js +1 -0
- package/dist/assets/guide_package-plugin-shop.md.D-xXN7Yg.js +9 -0
- package/dist/assets/guide_package-plugin-shop.md.D-xXN7Yg.lean.js +1 -0
- package/dist/assets/guide_package-plugin-sys-setting.md.Dx3nxHVF.js +9 -0
- package/dist/assets/guide_package-plugin-sys-setting.md.Dx3nxHVF.lean.js +1 -0
- package/dist/assets/guide_package-publishing.md.B7hzTYDH.js +7 -0
- package/dist/assets/guide_package-publishing.md.B7hzTYDH.lean.js +1 -0
- package/dist/assets/guide_package-request.md.DxaD65eM.js +195 -0
- package/dist/assets/guide_package-request.md.DxaD65eM.lean.js +1 -0
- package/dist/assets/guide_package-ui.md.wBZ_iQLb.js +50 -0
- package/dist/assets/guide_package-ui.md.wBZ_iQLb.lean.js +1 -0
- package/dist/assets/guide_permissions.md.B_5re4AR.js +83 -0
- package/dist/assets/guide_permissions.md.B_5re4AR.lean.js +1 -0
- package/dist/assets/guide_plugin-development.md.BQzTwLRr.js +226 -0
- package/dist/assets/guide_plugin-development.md.BQzTwLRr.lean.js +1 -0
- package/dist/assets/guide_plugins_admin-plugin.md.d_XC5U-4.js +52 -0
- package/dist/assets/guide_plugins_admin-plugin.md.d_XC5U-4.lean.js +1 -0
- package/dist/assets/guide_plugins_create-plugin.md.C-wDq4Un.js +109 -0
- package/dist/assets/guide_plugins_create-plugin.md.C-wDq4Un.lean.js +1 -0
- package/dist/assets/guide_plugins_debug-and-publish.md.CeTc01QN.js +92 -0
- package/dist/assets/guide_plugins_debug-and-publish.md.CeTc01QN.lean.js +1 -0
- package/dist/assets/guide_plugins_lifecycle-and-dependencies.md.BtwKS5jY.js +45 -0
- package/dist/assets/guide_plugins_lifecycle-and-dependencies.md.BtwKS5jY.lean.js +1 -0
- package/dist/assets/guide_plugins_permissions-and-settings.md.05CsB1I6.js +78 -0
- package/dist/assets/guide_plugins_permissions-and-settings.md.05CsB1I6.lean.js +1 -0
- package/dist/assets/guide_plugins_routes-menus-locales.md.B2dzO2DN.js +100 -0
- package/dist/assets/guide_plugins_routes-menus-locales.md.B2dzO2DN.lean.js +1 -0
- package/dist/assets/guide_pro-form.md.DbSHbrMu.js +116 -0
- package/dist/assets/guide_pro-form.md.DbSHbrMu.lean.js +1 -0
- package/dist/assets/guide_pro-table.md.DBuYQYgG.js +54 -0
- package/dist/assets/guide_pro-table.md.DBuYQYgG.lean.js +1 -0
- package/dist/assets/guide_request-and-components.md.BQXI_ZxY.js +175 -0
- package/dist/assets/guide_request-and-components.md.BQXI_ZxY.lean.js +1 -0
- package/dist/assets/guide_routing-and-menu.md.-zrm3BV9.js +74 -0
- package/dist/assets/guide_routing-and-menu.md.-zrm3BV9.lean.js +1 -0
- package/dist/assets/guide_theme-tokens.md.DXpbrOjS.js +53 -0
- package/dist/assets/guide_theme-tokens.md.DXpbrOjS.lean.js +1 -0
- package/dist/assets/index.md.BUgI8r98.js +1 -0
- package/dist/assets/index.md.BUgI8r98.lean.js +1 -0
- package/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/dist/assets/style.0snOvk0r.css +1 -0
- package/dist/guide/complete-host-app.html +198 -0
- package/dist/guide/create-project.html +58 -0
- package/dist/guide/deployment.html +66 -0
- package/dist/guide/dictionary-system.html +56 -0
- package/dist/guide/getting-started.html +33 -0
- package/dist/guide/host/auth-and-permissions.html +163 -0
- package/dist/guide/host/bootstrap.html +111 -0
- package/dist/guide/host/routing-and-menu.html +127 -0
- package/dist/guide/introduction.html +38 -0
- package/dist/guide/local-debugging.html +39 -0
- package/dist/guide/network-request.html +280 -0
- package/dist/guide/official-plugins/index.html +39 -0
- package/dist/guide/official-plugins/install-and-toggle.html +69 -0
- package/dist/guide/official-plugins/shop.html +73 -0
- package/dist/guide/official-plugins/sys-setting.html +50 -0
- package/dist/guide/package-core.html +69 -0
- package/dist/guide/package-ecosystem.html +25 -0
- package/dist/guide/package-plugin-shop.html +33 -0
- package/dist/guide/package-plugin-sys-setting.html +33 -0
- package/dist/guide/package-publishing.html +31 -0
- package/dist/guide/package-request.html +219 -0
- package/dist/guide/package-ui.html +74 -0
- package/dist/guide/permissions.html +107 -0
- package/dist/guide/plugin-development.html +250 -0
- package/dist/guide/plugins/admin-plugin.html +76 -0
- package/dist/guide/plugins/create-plugin.html +133 -0
- package/dist/guide/plugins/debug-and-publish.html +116 -0
- package/dist/guide/plugins/lifecycle-and-dependencies.html +69 -0
- package/dist/guide/plugins/permissions-and-settings.html +102 -0
- package/dist/guide/plugins/routes-menus-locales.html +124 -0
- package/dist/guide/pro-form.html +140 -0
- package/dist/guide/pro-table.html +78 -0
- package/dist/guide/request-and-components.html +199 -0
- package/dist/guide/routing-and-menu.html +98 -0
- package/dist/guide/theme-tokens.html +77 -0
- package/dist/hashmap.json +1 -0
- package/dist/index.html +25 -0
- package/dist/logo.png +0 -0
- package/dist/logo.svg +1 -0
- package/dist/vp-icons.css +1 -0
- package/dist/wechat-group-qr.png +0 -0
- package/package.json +24 -4
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en-US" dir="ltr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<title>@melt-js/libs-bag-request | Vue-Bag-Admin</title>
|
|
7
|
+
<meta name="description" content="基于 Vue3 + Vite6 + Naive UI + Pinia + Strapi5 的中后台系统框架">
|
|
8
|
+
<meta name="generator" content="VitePress v1.6.4">
|
|
9
|
+
<link rel="preload stylesheet" href="/@melt-js/docs-bag@2026.11.7/assets/style.0snOvk0r.css" as="style">
|
|
10
|
+
<link rel="preload stylesheet" href="/@melt-js/docs-bag@2026.11.7/vp-icons.css" as="style">
|
|
11
|
+
|
|
12
|
+
<script type="module" src="/@melt-js/docs-bag@2026.11.7/assets/app.CPZ-gtYR.js"></script>
|
|
13
|
+
<link rel="preload" href="/@melt-js/docs-bag@2026.11.7/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
+
<link rel="modulepreload" href="/@melt-js/docs-bag@2026.11.7/assets/chunks/theme.C4rSMcmz.js">
|
|
15
|
+
<link rel="modulepreload" href="/@melt-js/docs-bag@2026.11.7/assets/chunks/framework.B3lxS50j.js">
|
|
16
|
+
<link rel="modulepreload" href="/@melt-js/docs-bag@2026.11.7/assets/guide_package-request.md.DxaD65eM.lean.js">
|
|
17
|
+
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"dark",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
18
|
+
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
<div id="app"><div class="Layout" data-v-5d98c3a5><!--[--><!--]--><!--[--><span tabindex="-1" data-v-0b0ada53></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-0b0ada53>Skip to content</a><!--]--><!----><header class="VPNav" data-v-5d98c3a5 data-v-ae24b3ad><div class="VPNavBar" data-v-ae24b3ad data-v-6aa21345><div class="wrapper" data-v-6aa21345><div class="container" data-v-6aa21345><div class="title" data-v-6aa21345><div class="VPNavBarTitle has-sidebar" data-v-6aa21345 data-v-1168a8e4><a class="title" href="/@melt-js/docs-bag@2026.11.7/" data-v-1168a8e4><!--[--><!--]--><!--[--><img class="VPImage logo" src="/@melt-js/docs-bag@2026.11.7/logo.png" alt data-v-8426fc1a><!--]--><span data-v-1168a8e4>Vue-Bag-Admin</span><!--[--><!--]--></a></div></div><div class="content" data-v-6aa21345><div class="content-body" data-v-6aa21345><!--[--><!--]--><div class="VPNavBarSearch search" data-v-6aa21345><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-6aa21345 data-v-dc692963><span id="main-nav-aria-label" class="visually-hidden" data-v-dc692963> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/@melt-js/docs-bag@2026.11.7/" tabindex="0" data-v-dc692963 data-v-e56f3d57><!--[--><span data-v-e56f3d57>首页</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/@melt-js/docs-bag@2026.11.7/guide/introduction.html" tabindex="0" data-v-dc692963 data-v-e56f3d57><!--[--><span data-v-e56f3d57>指南</span><!--]--></a><!--]--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://hangjob.github.io/vue-bag-admin/" target="_blank" rel="noreferrer" tabindex="0" data-v-dc692963 data-v-e56f3d57><!--[--><span data-v-e56f3d57>在线预览</span><!--]--></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-dc692963 data-v-cf11d7a2><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-cf11d7a2><span class="text" data-v-cf11d7a2><!----><span data-v-cf11d7a2>社区</span><span class="vpi-chevron-down text-icon" data-v-cf11d7a2></span></span></button><div class="menu" data-v-cf11d7a2><div class="VPMenu" data-v-cf11d7a2 data-v-b98bc113><div class="items" data-v-b98bc113><!--[--><!--[--><div class="VPMenuLink" data-v-b98bc113 data-v-35975db6><a class="VPLink link" href="/@melt-js/docs-bag@2026.11.7/#community" data-v-35975db6><!--[--><span data-v-35975db6>微信群</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b98bc113 data-v-35975db6><a class="VPLink link vp-external-link-icon" href="https://www.itnavs.com/" target="_blank" rel="noreferrer" data-v-35975db6><!--[--><span data-v-35975db6>知航驿站</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-b98bc113 data-v-35975db6><a class="VPLink link vp-external-link-icon" href="https://yh.itnavs.com/contact" target="_blank" rel="noreferrer" data-v-35975db6><!--[--><span data-v-35975db6>合作机会</span><!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://www.npmjs.com/package/@melt-js/libs-bag-entry" target="_blank" rel="noreferrer" tabindex="0" data-v-dc692963 data-v-e56f3d57><!--[--><span data-v-e56f3d57>v2026.11.7</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-6aa21345 data-v-6c893767><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="true" data-v-6c893767 data-v-5337faa4 data-v-1d5665e3><span class="check" data-v-1d5665e3><span class="icon" data-v-1d5665e3><!--[--><span class="vpi-sun sun" data-v-5337faa4></span><span class="vpi-moon moon" data-v-5337faa4></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-6aa21345 data-v-0394ad82 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://github.com/hangjob/vue-bag-admin/tree/next" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-bd121fe5><span class="vpi-social-github"></span></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-6aa21345 data-v-bb2aa2f0 data-v-cf11d7a2><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-cf11d7a2><span class="vpi-more-horizontal icon" data-v-cf11d7a2></span></button><div class="menu" data-v-cf11d7a2><div class="VPMenu" data-v-cf11d7a2 data-v-b98bc113><!----><!--[--><!--[--><!----><div class="group" data-v-bb2aa2f0><div class="item appearance" data-v-bb2aa2f0><p class="label" data-v-bb2aa2f0>Appearance</p><div class="appearance-action" data-v-bb2aa2f0><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="true" data-v-bb2aa2f0 data-v-5337faa4 data-v-1d5665e3><span class="check" data-v-1d5665e3><span class="icon" data-v-1d5665e3><!--[--><span class="vpi-sun sun" data-v-5337faa4></span><span class="vpi-moon moon" data-v-5337faa4></span><!--]--></span></span></button></div></div></div><div class="group" data-v-bb2aa2f0><div class="item social-links" data-v-bb2aa2f0><div class="VPSocialLinks social-links-list" data-v-bb2aa2f0 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://github.com/hangjob/vue-bag-admin/tree/next" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-bd121fe5><span class="vpi-social-github"></span></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-6aa21345 data-v-e5dd9c1c><span class="container" data-v-e5dd9c1c><span class="top" data-v-e5dd9c1c></span><span class="middle" data-v-e5dd9c1c></span><span class="bottom" data-v-e5dd9c1c></span></span></button></div></div></div></div><div class="divider" data-v-6aa21345><div class="divider-line" data-v-6aa21345></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-5d98c3a5 data-v-a6f0e41e><div class="container" data-v-a6f0e41e><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-a6f0e41e><span class="vpi-align-left menu-icon" data-v-a6f0e41e></span><span class="menu-text" data-v-a6f0e41e>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-a6f0e41e data-v-8a42e2b4><button data-v-8a42e2b4>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-5d98c3a5 data-v-319d5ca6><div class="curtain" data-v-319d5ca6></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-319d5ca6><span class="visually-hidden" id="sidebar-aria-label" data-v-319d5ca6> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-c40bc020><section class="VPSidebarItem level-0" data-v-c40bc020 data-v-b3fd67f8><div class="item" role="button" tabindex="0" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><h2 class="text" data-v-b3fd67f8>开始使用</h2><!----></div><div class="items" data-v-b3fd67f8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/introduction.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>项目介绍</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/getting-started.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>快速上手</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/create-project.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>创建项目</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-c40bc020><section class="VPSidebarItem level-0" data-v-c40bc020 data-v-b3fd67f8><div class="item" role="button" tabindex="0" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><h2 class="text" data-v-b3fd67f8>核心开发</h2><!----></div><div class="items" data-v-b3fd67f8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/host/bootstrap.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>初始化宿主</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/host/routing-and-menu.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>路由与菜单</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/host/auth-and-permissions.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>登录与权限</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/request-and-components.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>请求与组件</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-c40bc020><section class="VPSidebarItem level-0" data-v-c40bc020 data-v-b3fd67f8><div class="item" role="button" tabindex="0" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><h2 class="text" data-v-b3fd67f8>官方插件</h2><!----></div><div class="items" data-v-b3fd67f8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/official-plugins/" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>插件总览</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/official-plugins/install-and-toggle.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>安装与启停</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/official-plugins/shop.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>商城插件</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/official-plugins/sys-setting.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>系统设置插件</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-c40bc020><section class="VPSidebarItem level-0" data-v-c40bc020 data-v-b3fd67f8><div class="item" role="button" tabindex="0" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><h2 class="text" data-v-b3fd67f8>插件开发</h2><!----></div><div class="items" data-v-b3fd67f8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/plugins/create-plugin.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>创建插件</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/plugins/admin-plugin.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>AdminPlugin 配置</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/plugins/routes-menus-locales.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>路由、菜单与多语言</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/plugins/permissions-and-settings.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>权限与配置项</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/plugins/lifecycle-and-dependencies.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>生命周期与依赖</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b3fd67f8><div class="item" data-v-b3fd67f8><div class="indicator" data-v-b3fd67f8></div><a class="VPLink link link" href="/@melt-js/docs-bag@2026.11.7/guide/plugins/debug-and-publish.html" data-v-b3fd67f8><!--[--><p class="text" data-v-b3fd67f8>调试与发布</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-5d98c3a5 data-v-1428d186><div class="VPDoc has-sidebar has-aside" data-v-1428d186 data-v-39a288b8><!--[--><!--]--><div class="container" data-v-39a288b8><div class="aside" data-v-39a288b8><div class="aside-curtain" data-v-39a288b8></div><div class="aside-container" data-v-39a288b8><div class="aside-content" data-v-39a288b8><div class="VPDocAside" data-v-39a288b8 data-v-3f215769><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-3f215769 data-v-a5bbad30><div class="content" data-v-a5bbad30><div class="outline-marker" data-v-a5bbad30></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-a5bbad30>On this page</div><ul class="VPDocOutlineItem root" data-v-a5bbad30 data-v-b933a997><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-3f215769></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-39a288b8><div class="content-container" data-v-39a288b8><!--[--><!--]--><main class="main" data-v-39a288b8><div style="position:relative;" class="vp-doc _@melt-js_docs-bag@2026_11_7_guide_package-request" data-v-39a288b8><div><h1 id="melt-js-libs-bag-request" tabindex="-1">@melt-js/libs-bag-request <a class="header-anchor" href="#melt-js-libs-bag-request" aria-label="Permalink to "@melt-js/libs-bag-request""></a></h1><p><code>@melt-js/libs-bag-request</code> 是请求层,把后台项目里常见的 HTTP 和 WebSocket 接入方式收在一起。</p><p>它不是为了替代 <code>axios</code> 或 <code>fetch</code>。它只是把 token 注入、异常对象、业务错误识别、WS 初始化这些重复动作先配好,业务页不用每次重写一遍。</p><h2 id="这里有什么" tabindex="-1">这里有什么 <a class="header-anchor" href="#这里有什么" aria-label="Permalink to "这里有什么""></a></h2><ul><li>默认导出的 <code>http</code> 实例</li><li><code>setupHttp()</code>:配置鉴权、错误处理与 <code>axios</code> 缓存策略</li><li><code>createHttpClient()</code>:创建独立的 axios 风格客户端,适合插件接不同服务</li><li><code>fetchHttp</code> / <code>setupFetch()</code>:给原生 <code>fetch</code> 一套同风格能力</li><li><code>http</code> / <code>fetch</code> 的 PWA 模式:离线缓存、断网入队、恢复后重放</li><li><code>createFetchClient()</code>:按需创建独立的 <code>fetch</code> 客户端</li><li><code>useRequest()</code>:把 <code>loading</code>、<code>data</code>、<code>error</code> 和 <code>run()</code> 这层执行状态收起来</li><li><code>debounceRequest()</code> / <code>throttleRequest()</code>:基于 Lodash 的高频请求控制</li><li><code>HttpError</code>:承载 HTTP 状态和业务载荷</li><li><code>setupWs()</code>:设置 WS token 与基础地址</li><li><code>createWsClient()</code>:创建轻量 WS 客户端</li></ul><h2 id="http-示例" tabindex="-1">HTTP 示例 <a class="header-anchor" href="#http-示例" aria-label="Permalink to "HTTP 示例""></a></h2><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { HttpError, http, setupHttp } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
22
|
+
<span class="line"></span>
|
|
23
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setupHttp</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
24
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> baseURL: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/api'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
25
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getToken</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
26
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> pwa: {</span></span>
|
|
27
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> enabled: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
28
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cache: {</span></span>
|
|
29
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> enabled: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
30
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> strategy: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'cache-first'</span></span>
|
|
31
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
32
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
33
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> onUnauthorized</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
34
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'redirect to login'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
35
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
36
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> resolveError</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">payload</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
37
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> data</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> payload </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">as</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">code</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> number</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">message</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
38
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (data?.code </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&&</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> data.code </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
39
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
40
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> code: data.code,</span></span>
|
|
41
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> message: data.message </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">??</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '业务失败'</span></span>
|
|
42
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
43
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
44
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span></span>
|
|
45
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
46
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
47
|
+
<span class="line"></span>
|
|
48
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
49
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> data</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> http.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/users/me'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
50
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(data)</span></span>
|
|
51
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error) {</span></span>
|
|
52
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">instanceof</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HttpError</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
53
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(error.status, error.code)</span></span>
|
|
54
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
55
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>现在 <code>http</code> 这条线也支持 PWA 缓存配置,适合继续沿用 <code>axios</code> 的项目。</p><p>如果插件要连接独立服务,不建议改全局 <code>http</code> 配置,可以创建自己的客户端:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { createHttpClient } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
56
|
+
<span class="line"></span>
|
|
57
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> reportHttp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createHttpClient</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
58
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> baseURL: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'https://report-api.example.com'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
59
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getToken</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report-token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
60
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> onUnauthorized</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
61
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report api unauthorized'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
62
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
63
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
64
|
+
<span class="line"></span>
|
|
65
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> summary</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> reportHttp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/summary'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><p>这样插件之间的 <code>baseURL</code>、token 和错误处理不会互相覆盖。</p><h2 id="websocket-示例" tabindex="-1">WebSocket 示例 <a class="header-anchor" href="#websocket-示例" aria-label="Permalink to "WebSocket 示例""></a></h2><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { createWsClient, setupWs } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
66
|
+
<span class="line"></span>
|
|
67
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setupWs</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
68
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getToken</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
69
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> baseURL: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'ws://localhost:8080'</span></span>
|
|
70
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
71
|
+
<span class="line"></span>
|
|
72
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> ws</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createWsClient</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/notice'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
73
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ws.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">open</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div><h2 id="fetch-示例" tabindex="-1">Fetch 示例 <a class="header-anchor" href="#fetch-示例" aria-label="Permalink to "Fetch 示例""></a></h2><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { HttpError, fetchHttp, setupFetch } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
74
|
+
<span class="line"></span>
|
|
75
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setupFetch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
76
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> baseURL: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/api'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
77
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getToken</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
78
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> onUnauthorized</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
79
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'redirect to login'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
80
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
81
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> resolveError</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">payload</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
82
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> data</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> payload </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">as</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">code</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> number</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">message</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
83
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (data?.code </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&&</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> data.code </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
84
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
85
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> code: data.code,</span></span>
|
|
86
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> message: data.message </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">??</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '业务失败'</span></span>
|
|
87
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
88
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
89
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span></span>
|
|
90
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
91
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
92
|
+
<span class="line"></span>
|
|
93
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
94
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> data</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fetchHttp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/users/me'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
95
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(data)</span></span>
|
|
96
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error) {</span></span>
|
|
97
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">instanceof</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HttpError</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
98
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(error.status, error.code)</span></span>
|
|
99
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
100
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h2 id="防抖和节流示例" tabindex="-1">防抖和节流示例 <a class="header-anchor" href="#防抖和节流示例" aria-label="Permalink to "防抖和节流示例""></a></h2><p>这两个工具底层还是 Lodash 的 <code>debounce</code> / <code>throttle</code>,只是外面包了一层请求友好的行为:返回值可以直接 <code>await</code>,也带 <code>cancel()</code>、<code>flush()</code>、<code>pending()</code>。</p><h3 id="搜索联想" tabindex="-1">搜索联想 <a class="header-anchor" href="#搜索联想" aria-label="Permalink to "搜索联想""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { debounceRequest, http } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
101
|
+
<span class="line"></span>
|
|
102
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> queryUsers</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> debounceRequest</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
103
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">keyword</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span></span>
|
|
104
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> http.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/users/search'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, {</span></span>
|
|
105
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> params: {</span></span>
|
|
106
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> keyword</span></span>
|
|
107
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
108
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }),</span></span>
|
|
109
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 300</span></span>
|
|
110
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
111
|
+
<span class="line"></span>
|
|
112
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> users</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> queryUsers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'bag admin'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><h3 id="自动保存" tabindex="-1">自动保存 <a class="header-anchor" href="#自动保存" aria-label="Permalink to "自动保存""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { fetchHttp, throttleRequest } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
113
|
+
<span class="line"></span>
|
|
114
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> saveDraft</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> throttleRequest</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
115
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">payload</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">title</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">content</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fetchHttp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">post</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/drafts'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, payload),</span></span>
|
|
116
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1000</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
117
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
118
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> leading: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
119
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> trailing: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
|
|
120
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
121
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
122
|
+
<span class="line"></span>
|
|
123
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> saveDraft</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
124
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'新草稿'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
125
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> content: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'节流保存'</span></span>
|
|
126
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre></div><h3 id="按钮防连点" tabindex="-1">按钮防连点 <a class="header-anchor" href="#按钮防连点" aria-label="Permalink to "按钮防连点""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { throttleRequest, http } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
127
|
+
<span class="line"></span>
|
|
128
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> submitOrder</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> throttleRequest</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
129
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">orderId</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span></span>
|
|
130
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> http.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">post</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/orders/submit'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, {</span></span>
|
|
131
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> orderId</span></span>
|
|
132
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }),</span></span>
|
|
133
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1500</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
134
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
135
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> leading: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
136
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> trailing: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span></span>
|
|
137
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
138
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
139
|
+
<span class="line"></span>
|
|
140
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> submitOrder</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'order_1001'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><h3 id="控制方法" tabindex="-1">控制方法 <a class="header-anchor" href="#控制方法" aria-label="Permalink to "控制方法""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { debounceRequest, http } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
141
|
+
<span class="line"></span>
|
|
142
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> queryUsers</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> debounceRequest</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
143
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">keyword</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span></span>
|
|
144
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> http.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/users/search'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, {</span></span>
|
|
145
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> params: {</span></span>
|
|
146
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> keyword</span></span>
|
|
147
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
148
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }),</span></span>
|
|
149
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 300</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
150
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
151
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> maxWait: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1000</span></span>
|
|
152
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
153
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
154
|
+
<span class="line"></span>
|
|
155
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">queryUsers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'bag'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
156
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">queryUsers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'bag a'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
157
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">queryUsers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'bag admin'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
158
|
+
<span class="line"></span>
|
|
159
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (queryUsers.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pending</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()) {</span></span>
|
|
160
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> queryUsers.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">flush</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
161
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
162
|
+
<span class="line"></span>
|
|
163
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">queryUsers.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">cancel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'page leave'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><p>适合这些场景:</p><ul><li>搜索联想、远程筛选这类只关心最后一次输入的读请求</li><li>自动保存、滚动加载这类要限速但不想完全丢掉后续动作的请求</li><li>按钮防连点、重复提交保护这类需要短时间内限制重复触发的提交动作</li></ul><h2 id="页面执行状态示例" tabindex="-1">页面执行状态示例 <a class="header-anchor" href="#页面执行状态示例" aria-label="Permalink to "页面执行状态示例""></a></h2><p>如果你只是想在页面里拿到 <code>loading</code>、<code>data</code>、<code>error</code> 和 <code>run()</code>,可以直接用 <code>useRequest()</code>,不用再自己手写一层状态管理。</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { http, useRequest } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
164
|
+
<span class="line"></span>
|
|
165
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">interface</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> UserProfile</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
166
|
+
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> id</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span></span>
|
|
167
|
+
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> nickname</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span></span>
|
|
168
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
169
|
+
<span class="line"></span>
|
|
170
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> userRequest</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useRequest</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">userId</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> http.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"><</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">UserProfile</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">>(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`/users/${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">userId</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">), {</span></span>
|
|
171
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> strategy: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'latest'</span></span>
|
|
172
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
173
|
+
<span class="line"></span>
|
|
174
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> userRequest.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">run</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'user_1'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
175
|
+
<span class="line"></span>
|
|
176
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(userRequest.loading.value)</span></span>
|
|
177
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(userRequest.data.value)</span></span>
|
|
178
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(userRequest.error.value)</span></span></code></pre></div><h3 id="对外方法" tabindex="-1">对外方法 <a class="header-anchor" href="#对外方法" aria-label="Permalink to "对外方法""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { fetchHttp, useRequest } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
179
|
+
<span class="line"></span>
|
|
180
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> articleRequest</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useRequest</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">((</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">articleId</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fetchHttp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`/articles/${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">articleId</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">), {</span></span>
|
|
181
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> defaultData: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">null</span></span>
|
|
182
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
183
|
+
<span class="line"></span>
|
|
184
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> articleRequest.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">run</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'article_1'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
185
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> articleRequest.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">refresh</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
186
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">articleRequest.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">cancel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'dialog closed'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
187
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">articleRequest.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">reset</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div><ul><li><code>loading</code>:当前这个请求控制器是否还有活跃任务</li><li><code>data</code>:最近一次有效成功结果</li><li><code>error</code>:最近一次有效失败结果</li><li><code>run(...args)</code>:执行请求并返回 <code>Promise</code></li><li><code>refresh()</code>:用上一次参数重新执行</li><li><code>cancel()</code>:让当前活跃请求失效,并立即退出当前控制器的 loading 统计</li><li><code>reset()</code>:清空当前控制器状态,并把 <code>data</code> 恢复到 <code>defaultData</code></li></ul><h3 id="并发策略" tabindex="-1">并发策略 <a class="header-anchor" href="#并发策略" aria-label="Permalink to "并发策略""></a></h3><p><code>useRequest()</code> 现在支持三种执行策略:</p><ul><li><code>latest</code>:默认值。新请求开始时,旧请求立即失效,适合搜索、筛选、切页</li><li><code>parallel</code>:允许多个请求并发执行,谁最后回来谁覆盖 <code>data</code></li><li><code>block</code>:执行中再次调用 <code>run()</code> 会直接抛错,适合按钮防重复提交</li></ul><h2 id="pwa-模式示例" tabindex="-1">PWA 模式示例 <a class="header-anchor" href="#pwa-模式示例" aria-label="Permalink to "PWA 模式示例""></a></h2><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { fetchHttp, replayOfflineQueue, setupFetch } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-request'</span></span>
|
|
188
|
+
<span class="line"></span>
|
|
189
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setupFetch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
190
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> baseURL: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/api'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
191
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getToken</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
192
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> onUnauthorized</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
193
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'redirect to login'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
194
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
195
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> pwa: {</span></span>
|
|
196
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> enabled: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
197
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cache: {</span></span>
|
|
198
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> enabled: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
199
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> strategy: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'cache-first'</span></span>
|
|
200
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
201
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> queue: {</span></span>
|
|
202
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> enabled: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
203
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> autoReplay: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
|
|
204
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
205
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
206
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
207
|
+
<span class="line"></span>
|
|
208
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> dashboard</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fetchHttp.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/dashboard'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, {</span></span>
|
|
209
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> pwa: {</span></span>
|
|
210
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> strategy: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'stale-while-revalidate'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
211
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ttl: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">60_000</span></span>
|
|
212
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
213
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
214
|
+
<span class="line"></span>
|
|
215
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> replayOfflineQueue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div><h2 id="谁会经常用到" tabindex="-1">谁会经常用到 <a class="header-anchor" href="#谁会经常用到" aria-label="Permalink to "谁会经常用到""></a></h2><ul><li>宿主项目:初始化请求层</li><li>业务插件:直接复用 <code>http</code> 和 WS 客户端</li><li>多端团队:把“错误码怎么识别、401 怎么收口”放到同一个地方</li></ul><h2 id="边界" tabindex="-1">边界 <a class="header-anchor" href="#边界" aria-label="Permalink to "边界""></a></h2><ul><li>它只负责接入层,不替你组织具体业务 API 模块</li><li>它默认返回提取后的数据,不是完整 <code>AxiosResponse</code></li><li><code>fetchHttp</code> 默认返回解析后的响应体,不是原始 <code>Response</code></li><li><code>debounceRequest()</code> 和 <code>throttleRequest()</code> 只控制调用频率,不会中断已经发出的请求</li><li><code>useRequest()</code> 负责页面执行状态,不会替你拆业务 API,也不会直接中断已发出的网络请求</li><li>开启 PWA 缓存后,<code>http</code> 和 <code>fetchHttp</code> 的读请求都会优先读取本地缓存</li><li>PWA 模式只增强请求层,不负责 manifest、Service Worker 注册与安装提示</li><li>如果后端响应结构有差异,通过 <code>setupHttp()</code> 或 <code>setupFetch()</code> 适配</li></ul><h2 id="继续阅读" tabindex="-1">继续阅读 <a class="header-anchor" href="#继续阅读" aria-label="Permalink to "继续阅读""></a></h2><ul><li><a href="./network-request.html">网络请求与拦截</a></li></ul></div></div></main><footer class="VPDocFooter" data-v-39a288b8 data-v-e257564d><!--[--><!--]--><div class="edit-info" data-v-e257564d><!----><div class="last-updated" data-v-e257564d><p class="VPLastUpdated" data-v-e257564d data-v-e98dd255>Last updated: <time datetime="2026-11-07T09:53:20.000Z" data-v-e98dd255></time></p></div></div><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-e257564d><span class="visually-hidden" id="doc-footer-aria-label" data-v-e257564d>Pager</span><div class="pager" data-v-e257564d><!----></div><div class="pager" data-v-e257564d><a class="VPLink link pager-link next" href="/@melt-js/docs-bag@2026.11.7/guide/introduction.html" data-v-e257564d><!--[--><span class="desc" data-v-e257564d>Next page</span><span class="title" data-v-e257564d>项目介绍</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-5d98c3a5 data-v-e315a0ad><div class="container" data-v-e315a0ad><p class="message" data-v-e315a0ad>Released under the MIT License.</p><p class="copyright" data-v-e315a0ad>Copyright © 2026-present Vue-Bag-Admin</p></div></footer><!--[--><!--]--></div></div>
|
|
216
|
+
<script>window.__VP_HASH_MAP__=JSON.parse("{\"guide_complete-host-app.md\":\"CDRzLz0E\",\"guide_create-project.md\":\"LRNhDD9x\",\"guide_deployment.md\":\"B8aEUabm\",\"guide_dictionary-system.md\":\"Dy0tQYMR\",\"guide_getting-started.md\":\"B-mobXxi\",\"guide_host_auth-and-permissions.md\":\"DWH3Vape\",\"guide_host_bootstrap.md\":\"DpbxPIZw\",\"guide_host_routing-and-menu.md\":\"BdCMIOxn\",\"guide_introduction.md\":\"1MiCcWyO\",\"guide_local-debugging.md\":\"CLJoKVb9\",\"guide_network-request.md\":\"DDlA8bc0\",\"guide_official-plugins_index.md\":\"DPwemCGy\",\"guide_official-plugins_install-and-toggle.md\":\"Eq2hWjYn\",\"guide_official-plugins_shop.md\":\"yBltEx-o\",\"guide_official-plugins_sys-setting.md\":\"BmkuOqGv\",\"guide_package-core.md\":\"-E29SYy8\",\"guide_package-ecosystem.md\":\"Di3RcVpF\",\"guide_package-plugin-shop.md\":\"D-xXN7Yg\",\"guide_package-plugin-sys-setting.md\":\"Dx3nxHVF\",\"guide_package-publishing.md\":\"B7hzTYDH\",\"guide_package-request.md\":\"DxaD65eM\",\"guide_package-ui.md\":\"wBZ_iQLb\",\"guide_permissions.md\":\"B_5re4AR\",\"guide_plugin-development.md\":\"BQzTwLRr\",\"guide_plugins_admin-plugin.md\":\"d_XC5U-4\",\"guide_plugins_create-plugin.md\":\"C-wDq4Un\",\"guide_plugins_debug-and-publish.md\":\"CeTc01QN\",\"guide_plugins_lifecycle-and-dependencies.md\":\"BtwKS5jY\",\"guide_plugins_permissions-and-settings.md\":\"05CsB1I6\",\"guide_plugins_routes-menus-locales.md\":\"B2dzO2DN\",\"guide_pro-form.md\":\"DbSHbrMu\",\"guide_pro-table.md\":\"DBuYQYgG\",\"guide_request-and-components.md\":\"BQXI_ZxY\",\"guide_routing-and-menu.md\":\"-zrm3BV9\",\"guide_theme-tokens.md\":\"DXpbrOjS\",\"index.md\":\"BUgI8r98\",\"readme.md\":\"BEUJStMI\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Vue-Bag-Admin\",\"description\":\"基于 Vue3 + Vite6 + Naive UI + Pinia + Strapi5 的中后台系统框架\",\"base\":\"/@melt-js/docs-bag@2026.11.7/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":\"dark\",\"themeConfig\":{\"logo\":\"/logo.png\",\"nav\":[{\"text\":\"首页\",\"link\":\"/\"},{\"text\":\"指南\",\"link\":\"/guide/introduction\"},{\"text\":\"在线预览\",\"link\":\"https://hangjob.github.io/vue-bag-admin/\"},{\"text\":\"社区\",\"items\":[{\"text\":\"微信群\",\"link\":\"/#community\"},{\"text\":\"知航驿站\",\"link\":\"https://www.itnavs.com/\"},{\"text\":\"合作机会\",\"link\":\"https://yh.itnavs.com/contact\"}]},{\"text\":\"v2026.11.7\",\"link\":\"https://www.npmjs.com/package/@melt-js/libs-bag-entry\"}],\"sidebar\":{\"/guide/\":[{\"text\":\"开始使用\",\"items\":[{\"text\":\"项目介绍\",\"link\":\"/guide/introduction\"},{\"text\":\"快速上手\",\"link\":\"/guide/getting-started\"},{\"text\":\"创建项目\",\"link\":\"/guide/create-project\"}]},{\"text\":\"核心开发\",\"items\":[{\"text\":\"初始化宿主\",\"link\":\"/guide/host/bootstrap\"},{\"text\":\"路由与菜单\",\"link\":\"/guide/host/routing-and-menu\"},{\"text\":\"登录与权限\",\"link\":\"/guide/host/auth-and-permissions\"},{\"text\":\"请求与组件\",\"link\":\"/guide/request-and-components\"}]},{\"text\":\"官方插件\",\"items\":[{\"text\":\"插件总览\",\"link\":\"/guide/official-plugins/\"},{\"text\":\"安装与启停\",\"link\":\"/guide/official-plugins/install-and-toggle\"},{\"text\":\"商城插件\",\"link\":\"/guide/official-plugins/shop\"},{\"text\":\"系统设置插件\",\"link\":\"/guide/official-plugins/sys-setting\"}]},{\"text\":\"插件开发\",\"items\":[{\"text\":\"创建插件\",\"link\":\"/guide/plugins/create-plugin\"},{\"text\":\"AdminPlugin 配置\",\"link\":\"/guide/plugins/admin-plugin\"},{\"text\":\"路由、菜单与多语言\",\"link\":\"/guide/plugins/routes-menus-locales\"},{\"text\":\"权限与配置项\",\"link\":\"/guide/plugins/permissions-and-settings\"},{\"text\":\"生命周期与依赖\",\"link\":\"/guide/plugins/lifecycle-and-dependencies\"},{\"text\":\"调试与发布\",\"link\":\"/guide/plugins/debug-and-publish\"}]}]},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/hangjob/vue-bag-admin/tree/next\"}],\"footer\":{\"message\":\"Released under the MIT License.\",\"copyright\":\"Copyright © 2026-present Vue-Bag-Admin\"},\"search\":{\"provider\":\"local\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
|
|
217
|
+
|
|
218
|
+
</body>
|
|
219
|
+
</html>
|