@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.
Files changed (139) hide show
  1. package/README.md +32 -2
  2. package/dist/404.html +22 -0
  3. package/dist/README.html +33 -0
  4. package/dist/assets/README.md.BEUJStMI.js +9 -0
  5. package/dist/assets/README.md.BEUJStMI.lean.js +1 -0
  6. package/dist/assets/app.CPZ-gtYR.js +1 -0
  7. package/dist/assets/chunks/@localSearchIndexroot.7ill5i5O.js +1 -0
  8. package/dist/assets/chunks/VPLocalSearchBox.BVA3GWxn.js +9 -0
  9. package/dist/assets/chunks/framework.B3lxS50j.js +20 -0
  10. package/dist/assets/chunks/theme.C4rSMcmz.js +2 -0
  11. package/dist/assets/guide_complete-host-app.md.CDRzLz0E.js +174 -0
  12. package/dist/assets/guide_complete-host-app.md.CDRzLz0E.lean.js +1 -0
  13. package/dist/assets/guide_create-project.md.LRNhDD9x.js +34 -0
  14. package/dist/assets/guide_create-project.md.LRNhDD9x.lean.js +1 -0
  15. package/dist/assets/guide_deployment.md.B8aEUabm.js +42 -0
  16. package/dist/assets/guide_deployment.md.B8aEUabm.lean.js +1 -0
  17. package/dist/assets/guide_dictionary-system.md.Dy0tQYMR.js +32 -0
  18. package/dist/assets/guide_dictionary-system.md.Dy0tQYMR.lean.js +1 -0
  19. package/dist/assets/guide_getting-started.md.B-mobXxi.js +9 -0
  20. package/dist/assets/guide_getting-started.md.B-mobXxi.lean.js +1 -0
  21. package/dist/assets/guide_host_auth-and-permissions.md.DWH3Vape.js +139 -0
  22. package/dist/assets/guide_host_auth-and-permissions.md.DWH3Vape.lean.js +1 -0
  23. package/dist/assets/guide_host_bootstrap.md.DpbxPIZw.js +87 -0
  24. package/dist/assets/guide_host_bootstrap.md.DpbxPIZw.lean.js +1 -0
  25. package/dist/assets/guide_host_routing-and-menu.md.BdCMIOxn.js +103 -0
  26. package/dist/assets/guide_host_routing-and-menu.md.BdCMIOxn.lean.js +1 -0
  27. package/dist/assets/guide_introduction.md.1MiCcWyO.js +14 -0
  28. package/dist/assets/guide_introduction.md.1MiCcWyO.lean.js +1 -0
  29. package/dist/assets/guide_local-debugging.md.CLJoKVb9.js +15 -0
  30. package/dist/assets/guide_local-debugging.md.CLJoKVb9.lean.js +1 -0
  31. package/dist/assets/guide_network-request.md.DDlA8bc0.js +256 -0
  32. package/dist/assets/guide_network-request.md.DDlA8bc0.lean.js +1 -0
  33. package/dist/assets/guide_official-plugins_index.md.DPwemCGy.js +15 -0
  34. package/dist/assets/guide_official-plugins_index.md.DPwemCGy.lean.js +1 -0
  35. package/dist/assets/guide_official-plugins_install-and-toggle.md.Eq2hWjYn.js +45 -0
  36. package/dist/assets/guide_official-plugins_install-and-toggle.md.Eq2hWjYn.lean.js +1 -0
  37. package/dist/assets/guide_official-plugins_shop.md.yBltEx-o.js +49 -0
  38. package/dist/assets/guide_official-plugins_shop.md.yBltEx-o.lean.js +1 -0
  39. package/dist/assets/guide_official-plugins_sys-setting.md.BmkuOqGv.js +26 -0
  40. package/dist/assets/guide_official-plugins_sys-setting.md.BmkuOqGv.lean.js +1 -0
  41. package/dist/assets/guide_package-core.md.-E29SYy8.js +45 -0
  42. package/dist/assets/guide_package-core.md.-E29SYy8.lean.js +1 -0
  43. package/dist/assets/guide_package-ecosystem.md.Di3RcVpF.js +1 -0
  44. package/dist/assets/guide_package-ecosystem.md.Di3RcVpF.lean.js +1 -0
  45. package/dist/assets/guide_package-plugin-shop.md.D-xXN7Yg.js +9 -0
  46. package/dist/assets/guide_package-plugin-shop.md.D-xXN7Yg.lean.js +1 -0
  47. package/dist/assets/guide_package-plugin-sys-setting.md.Dx3nxHVF.js +9 -0
  48. package/dist/assets/guide_package-plugin-sys-setting.md.Dx3nxHVF.lean.js +1 -0
  49. package/dist/assets/guide_package-publishing.md.B7hzTYDH.js +7 -0
  50. package/dist/assets/guide_package-publishing.md.B7hzTYDH.lean.js +1 -0
  51. package/dist/assets/guide_package-request.md.DxaD65eM.js +195 -0
  52. package/dist/assets/guide_package-request.md.DxaD65eM.lean.js +1 -0
  53. package/dist/assets/guide_package-ui.md.wBZ_iQLb.js +50 -0
  54. package/dist/assets/guide_package-ui.md.wBZ_iQLb.lean.js +1 -0
  55. package/dist/assets/guide_permissions.md.B_5re4AR.js +83 -0
  56. package/dist/assets/guide_permissions.md.B_5re4AR.lean.js +1 -0
  57. package/dist/assets/guide_plugin-development.md.BQzTwLRr.js +226 -0
  58. package/dist/assets/guide_plugin-development.md.BQzTwLRr.lean.js +1 -0
  59. package/dist/assets/guide_plugins_admin-plugin.md.d_XC5U-4.js +52 -0
  60. package/dist/assets/guide_plugins_admin-plugin.md.d_XC5U-4.lean.js +1 -0
  61. package/dist/assets/guide_plugins_create-plugin.md.C-wDq4Un.js +109 -0
  62. package/dist/assets/guide_plugins_create-plugin.md.C-wDq4Un.lean.js +1 -0
  63. package/dist/assets/guide_plugins_debug-and-publish.md.CeTc01QN.js +92 -0
  64. package/dist/assets/guide_plugins_debug-and-publish.md.CeTc01QN.lean.js +1 -0
  65. package/dist/assets/guide_plugins_lifecycle-and-dependencies.md.BtwKS5jY.js +45 -0
  66. package/dist/assets/guide_plugins_lifecycle-and-dependencies.md.BtwKS5jY.lean.js +1 -0
  67. package/dist/assets/guide_plugins_permissions-and-settings.md.05CsB1I6.js +78 -0
  68. package/dist/assets/guide_plugins_permissions-and-settings.md.05CsB1I6.lean.js +1 -0
  69. package/dist/assets/guide_plugins_routes-menus-locales.md.B2dzO2DN.js +100 -0
  70. package/dist/assets/guide_plugins_routes-menus-locales.md.B2dzO2DN.lean.js +1 -0
  71. package/dist/assets/guide_pro-form.md.DbSHbrMu.js +116 -0
  72. package/dist/assets/guide_pro-form.md.DbSHbrMu.lean.js +1 -0
  73. package/dist/assets/guide_pro-table.md.DBuYQYgG.js +54 -0
  74. package/dist/assets/guide_pro-table.md.DBuYQYgG.lean.js +1 -0
  75. package/dist/assets/guide_request-and-components.md.BQXI_ZxY.js +175 -0
  76. package/dist/assets/guide_request-and-components.md.BQXI_ZxY.lean.js +1 -0
  77. package/dist/assets/guide_routing-and-menu.md.-zrm3BV9.js +74 -0
  78. package/dist/assets/guide_routing-and-menu.md.-zrm3BV9.lean.js +1 -0
  79. package/dist/assets/guide_theme-tokens.md.DXpbrOjS.js +53 -0
  80. package/dist/assets/guide_theme-tokens.md.DXpbrOjS.lean.js +1 -0
  81. package/dist/assets/index.md.BUgI8r98.js +1 -0
  82. package/dist/assets/index.md.BUgI8r98.lean.js +1 -0
  83. package/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
  84. package/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
  85. package/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
  86. package/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
  87. package/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
  88. package/dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
  89. package/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
  90. package/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
  91. package/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
  92. package/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
  93. package/dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
  94. package/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
  95. package/dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
  96. package/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
  97. package/dist/assets/style.0snOvk0r.css +1 -0
  98. package/dist/guide/complete-host-app.html +198 -0
  99. package/dist/guide/create-project.html +58 -0
  100. package/dist/guide/deployment.html +66 -0
  101. package/dist/guide/dictionary-system.html +56 -0
  102. package/dist/guide/getting-started.html +33 -0
  103. package/dist/guide/host/auth-and-permissions.html +163 -0
  104. package/dist/guide/host/bootstrap.html +111 -0
  105. package/dist/guide/host/routing-and-menu.html +127 -0
  106. package/dist/guide/introduction.html +38 -0
  107. package/dist/guide/local-debugging.html +39 -0
  108. package/dist/guide/network-request.html +280 -0
  109. package/dist/guide/official-plugins/index.html +39 -0
  110. package/dist/guide/official-plugins/install-and-toggle.html +69 -0
  111. package/dist/guide/official-plugins/shop.html +73 -0
  112. package/dist/guide/official-plugins/sys-setting.html +50 -0
  113. package/dist/guide/package-core.html +69 -0
  114. package/dist/guide/package-ecosystem.html +25 -0
  115. package/dist/guide/package-plugin-shop.html +33 -0
  116. package/dist/guide/package-plugin-sys-setting.html +33 -0
  117. package/dist/guide/package-publishing.html +31 -0
  118. package/dist/guide/package-request.html +219 -0
  119. package/dist/guide/package-ui.html +74 -0
  120. package/dist/guide/permissions.html +107 -0
  121. package/dist/guide/plugin-development.html +250 -0
  122. package/dist/guide/plugins/admin-plugin.html +76 -0
  123. package/dist/guide/plugins/create-plugin.html +133 -0
  124. package/dist/guide/plugins/debug-and-publish.html +116 -0
  125. package/dist/guide/plugins/lifecycle-and-dependencies.html +69 -0
  126. package/dist/guide/plugins/permissions-and-settings.html +102 -0
  127. package/dist/guide/plugins/routes-menus-locales.html +124 -0
  128. package/dist/guide/pro-form.html +140 -0
  129. package/dist/guide/pro-table.html +78 -0
  130. package/dist/guide/request-and-components.html +199 -0
  131. package/dist/guide/routing-and-menu.html +98 -0
  132. package/dist/guide/theme-tokens.html +77 -0
  133. package/dist/hashmap.json +1 -0
  134. package/dist/index.html +25 -0
  135. package/dist/logo.png +0 -0
  136. package/dist/logo.svg +1 -0
  137. package/dist/vp-icons.css +1 -0
  138. package/dist/wechat-group-qr.png +0 -0
  139. package/package.json +24 -4
@@ -0,0 +1,87 @@
1
+ import{_ as i,o as a,c as n,a2 as p}from"./chunks/framework.B3lxS50j.js";const g=JSON.parse('{"title":"初始化宿主","description":"","frontmatter":{},"headers":[],"relativePath":"guide/host/bootstrap.md","filePath":"guide/host/bootstrap.md","lastUpdated":1794045200000}'),l={name:"guide/host/bootstrap.md"};function t(h,s,k,e,E,r){return a(),n("div",null,[...s[0]||(s[0]=[p(`<h1 id="初始化宿主" tabindex="-1">初始化宿主 <a class="header-anchor" href="#初始化宿主" aria-label="Permalink to &quot;初始化宿主&quot;">​</a></h1><p>宿主初始化的目标,是把 Vue 应用、状态管理、国际化、路由和插件运行时连接起来。</p><p>这一页先使用最小配置启动宿主。登录、权限和请求会在后续章节逐步加入。</p><h2 id="最小入口" tabindex="-1">最小入口 <a class="header-anchor" href="#最小入口" aria-label="Permalink to &quot;最小入口&quot;">​</a></h2><p><code>src/main.ts</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;"> { createApp } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;vue&#39;</span></span>
2
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { createPinia } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;pinia&#39;</span></span>
3
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { bootstrapPlugins, createHostI18n, createHostRouter } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@melt-js/libs-bag-entry&#39;</span></span>
4
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> App </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./App.vue&#39;</span></span>
5
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { appRoutes } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./routes&#39;</span></span>
6
+ <span class="line"></span>
7
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@melt-js/libs-bag-entry/style.css&#39;</span></span>
8
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./style.css&#39;</span></span>
9
+ <span class="line"></span>
10
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">async</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setupApp</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() {</span></span>
11
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> app</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createApp</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(App)</span></span>
12
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> pinia</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createPinia</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
13
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> i18n</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createHostI18n</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
14
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> router</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createHostRouter</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
15
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> routes: appRoutes,</span></span>
16
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> auth: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span></span>
17
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span>
18
+ <span class="line"></span>
19
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> app.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">use</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(pinia)</span></span>
20
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> app.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">use</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(i18n)</span></span>
21
+ <span class="line"></span>
22
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> bootstrapPlugins</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
23
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> app,</span></span>
24
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> router,</span></span>
25
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i18n,</span></span>
26
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> plugins: []</span></span>
27
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span>
28
+ <span class="line"></span>
29
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> router.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">isReady</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
30
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> app.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">mount</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;#app&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
31
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
32
+ <span class="line"></span>
33
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setupApp</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div><p><code>src/App.vue</code>:</p><div class="language-vue vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">vue</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
34
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">HostApp</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /&gt;</span></span>
35
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
36
+ <span class="line"></span>
37
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setup</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> lang</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;ts&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
38
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { HostApp } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@melt-js/libs-bag-entry&#39;</span></span>
39
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span></code></pre></div><p><code>src/routes.ts</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:#D73A49;--shiki-dark:#F97583;"> type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { AdminRouteRecordRaw } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@melt-js/libs-bag-entry&#39;</span></span>
40
+ <span class="line"></span>
41
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> appRoutes</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AdminRouteRecordRaw</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>
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;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
44
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> redirect: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/dashboard&#39;</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 style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/dashboard&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
48
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;Dashboard&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
49
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> component</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;./views/Dashboard.vue&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
50
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> meta: {</span></span>
51
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;Dashboard&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
52
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> layout: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;default&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
53
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> public: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</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>
56
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
57
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/404&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
58
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;NotFound&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
59
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> component</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;./views/NotFound.vue&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
60
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> meta: {</span></span>
61
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> layout: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;default&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
62
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> public: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
63
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
64
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
65
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
66
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/:pathMatch(.*)*&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
67
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> redirect: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/404&#39;</span></span>
68
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
69
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span></code></pre></div><p>现在访问 <code>/dashboard</code>,就能看到带默认布局的宿主页面。</p><h2 id="初始化顺序" tabindex="-1">初始化顺序 <a class="header-anchor" href="#初始化顺序" aria-label="Permalink to &quot;初始化顺序&quot;">​</a></h2><p>入口代码看起来不多,但顺序很重要。</p><h3 id="_1-创建基础实例" tabindex="-1">1. 创建基础实例 <a class="header-anchor" href="#_1-创建基础实例" aria-label="Permalink to &quot;1. 创建基础实例&quot;">​</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;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> app</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createApp</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(App)</span></span>
70
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> pinia</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createPinia</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
71
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> i18n</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createHostI18n</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
72
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> router</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createHostRouter</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ routes: appRoutes, auth: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span></code></pre></div><ul><li><code>createHostI18n()</code> 提供宿主内置词条和插件语言包合并能力。</li><li><code>createHostRouter()</code> 创建路由,并根据 <code>auth</code> 决定是否启用登录与权限守卫。</li><li><code>auth: false</code> 只适合无登录系统或宿主接入初期。</li></ul><h3 id="_2-先安装-pinia-和-i18n" tabindex="-1">2. 先安装 Pinia 和 i18n <a class="header-anchor" href="#_2-先安装-pinia-和-i18n" aria-label="Permalink to &quot;2. 先安装 Pinia 和 i18n&quot;">​</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:#24292E;--shiki-dark:#E1E4E8;">app.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">use</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(pinia)</span></span>
73
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">app.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">use</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(i18n)</span></span></code></pre></div><p>后面的插件引导、用户状态和菜单状态会读取 Pinia,因此不要把它放到 <code>bootstrapPlugins()</code> 后面。</p><h3 id="_3-引导插件" tabindex="-1">3. 引导插件 <a class="header-anchor" href="#_3-引导插件" aria-label="Permalink to &quot;3. 引导插件&quot;">​</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;">await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> bootstrapPlugins</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
74
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> app,</span></span>
75
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> router,</span></span>
76
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i18n,</span></span>
77
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> plugins: []</span></span>
78
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre></div><p><code>bootstrapPlugins()</code> 会:</p><ol><li>初始化宿主 UI。</li><li>过滤并排序插件。</li><li>检查插件、路由和菜单冲突。</li><li>注册插件路由。</li><li>合并插件菜单和语言包。</li><li>执行插件 <code>install</code>。</li><li>把 Router 安装到 Vue 应用。</li></ol><p>因此,不需要再单独调用 <code>app.use(router)</code>。</p><h3 id="_4-等待路由后再挂载" tabindex="-1">4. 等待路由后再挂载 <a class="header-anchor" href="#_4-等待路由后再挂载" aria-label="Permalink to &quot;4. 等待路由后再挂载&quot;">​</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;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> router.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">isReady</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
79
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">app.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">mount</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;#app&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><p>插件路由是异步引导阶段注册的。等待 Router 准备完成,可以避免首屏路由尚未注册就开始渲染。</p><h2 id="样式顺序" tabindex="-1">样式顺序 <a class="header-anchor" href="#样式顺序" aria-label="Permalink to &quot;样式顺序&quot;">​</a></h2><p>框架样式必须先于项目样式:</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:#032F62;--shiki-dark:#9ECBFF;"> &#39;@melt-js/libs-bag-entry/style.css&#39;</span></span>
80
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./style.css&#39;</span></span></code></pre></div><p>这样项目可以覆盖框架变量和局部样式。顺序写反时,常见表现是主题色、自定义布局或 Tailwind 样式没有生效。</p><h2 id="加载本地插件" tabindex="-1">加载本地插件 <a class="header-anchor" href="#加载本地插件" aria-label="Permalink to &quot;加载本地插件&quot;">​</a></h2><p>准备好业务插件后,只需要把它传入 <code>plugins</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;"> workspacePlugin </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./plugins/workspace&#39;</span></span>
81
+ <span class="line"></span>
82
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> bootstrapPlugins</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
83
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> app,</span></span>
84
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> router,</span></span>
85
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i18n,</span></span>
86
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> plugins: [workspacePlugin]</span></span>
87
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre></div><p>插件数组的书写顺序不是最终注册顺序。运行时会优先根据每个插件的 <code>order</code> 排序。</p><h2 id="从最小宿主升级" tabindex="-1">从最小宿主升级 <a class="header-anchor" href="#从最小宿主升级" aria-label="Permalink to &quot;从最小宿主升级&quot;">​</a></h2><p>一个真实后台通常还需要:</p><ul><li><code>setAuthProvider()</code>:接入真实登录系统。</li><li><code>registerPermissionDirective()</code>:注册 <code>v-permission</code>。</li><li><code>setupHttp()</code>:注入接口地址、token 和错误处理。</li><li><code>bootstrapPlugins({ plugins })</code>:加载业务插件。</li></ul><p>不要一次把所有能力都塞进入口。建议先确保宿主与路由正常,再依次接认证、插件和请求。</p><h2 id="下一步" tabindex="-1">下一步 <a class="header-anchor" href="#下一步" aria-label="Permalink to &quot;下一步&quot;">​</a></h2><p>继续阅读 <a href="./routing-and-menu.html">路由与菜单</a>,先建立“页面能访问”和“页面出现在导航中”之间的关系。</p>`,41)])])}const o=i(l,[["render",t]]);export{g as __pageData,o as default};
@@ -0,0 +1 @@
1
+ import{_ as i,o as a,c as n,a2 as p}from"./chunks/framework.B3lxS50j.js";const g=JSON.parse('{"title":"初始化宿主","description":"","frontmatter":{},"headers":[],"relativePath":"guide/host/bootstrap.md","filePath":"guide/host/bootstrap.md","lastUpdated":1794045200000}'),l={name:"guide/host/bootstrap.md"};function t(h,s,k,e,E,r){return a(),n("div",null,[...s[0]||(s[0]=[p("",41)])])}const o=i(l,[["render",t]]);export{g as __pageData,o as default};
@@ -0,0 +1,103 @@
1
+ import{_ as i,o as a,c as n,a2 as t}from"./chunks/framework.B3lxS50j.js";const g=JSON.parse('{"title":"路由与菜单","description":"","frontmatter":{},"headers":[],"relativePath":"guide/host/routing-and-menu.md","filePath":"guide/host/routing-and-menu.md","lastUpdated":1794045200000}'),h={name:"guide/host/routing-and-menu.md"};function l(p,s,k,e,E,d){return a(),n("div",null,[...s[0]||(s[0]=[t(`<h1 id="路由与菜单" tabindex="-1">路由与菜单 <a class="header-anchor" href="#路由与菜单" aria-label="Permalink to &quot;路由与菜单&quot;">​</a></h1><p>在 Vue-Bag-Admin 中,路由和菜单是两份配置:</p><ul><li>路由决定一个地址能否访问、渲染哪个页面、使用什么布局。</li><li>菜单决定侧边栏显示什么、如何分组和排序。</li></ul><p>两者通常使用相同的 <code>path</code> 建立关联,但不会自动互相生成。</p><h2 id="宿主路由和插件路由" tabindex="-1">宿主路由和插件路由 <a class="header-anchor" href="#宿主路由和插件路由" aria-label="Permalink to &quot;宿主路由和插件路由&quot;">​</a></h2><p>宿主路由通过 <code>createHostRouter()</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;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> router</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createHostRouter</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
2
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> routes: appRoutes,</span></span>
3
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> auth: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
4
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre></div><p>它们适合放登录页、Dashboard、403、404 等应用级页面。</p><p>业务路由通常由插件提供:</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;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> contentPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AdminPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
5
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> id: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;content-plugin&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
6
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;内容插件&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
7
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> version: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;1.0.0&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
8
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> routes: [</span></span>
9
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
10
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/content/posts&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
11
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;ContentPosts&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
12
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> component</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;../views/ContentPosts.vue&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
13
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> meta: {</span></span>
14
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;content.posts&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
15
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> layout: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;default&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
16
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> roles: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;authenticated&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
17
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
18
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
19
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ]</span></span>
20
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p><code>bootstrapPlugins()</code> 会在应用挂载前把这些路由加入 Router。</p><h2 id="路由-meta" tabindex="-1">路由 Meta <a class="header-anchor" href="#路由-meta" aria-label="Permalink to &quot;路由 Meta&quot;">​</a></h2><p>后台行为通过 <code>meta</code> 描述:</p><table tabindex="0"><thead><tr><th>字段</th><th>作用</th></tr></thead><tbody><tr><td><code>title</code></td><td>页面标题,可以使用 i18n key</td></tr><tr><td><code>layout</code></td><td>布局名称,常用 <code>default</code> 或 <code>blank</code></td></tr><tr><td><code>public</code></td><td>是否允许未登录访问</td></tr><tr><td><code>roles</code></td><td>允许访问的角色</td></tr><tr><td><code>roleMode</code></td><td>角色匹配模式:<code>any</code> 或 <code>all</code></td></tr><tr><td><code>permissions</code></td><td>允许访问的权限点</td></tr><tr><td><code>permissionMode</code></td><td>权限匹配模式:<code>any</code> 或 <code>all</code></td></tr><tr><td><code>policy</code></td><td>自定义权限判断函数</td></tr><tr><td><code>activeMenu</code></td><td>当前页面应该高亮的菜单路径</td></tr><tr><td><code>noCache</code></td><td>是否跳过页面缓存</td></tr><tr><td><code>cacheKey</code></td><td>多个路由复用组件时使用的缓存键</td></tr></tbody></table><p>登录页一般使用空白布局并公开访问:</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:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
21
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> path</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/login&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
22
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;Login&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
23
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> component</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;./views/Login.vue&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
24
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> meta</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
25
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> layout</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;blank&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
26
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> public</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
27
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
28
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>详情页一般不配置菜单,而是通过 <code>activeMenu</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:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
29
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> path</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/content/posts/:id&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
30
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;ContentPostDetail&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
31
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> component</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;./views/ContentPostDetail.vue&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
32
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> meta</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
33
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> title</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;content.detail&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
34
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> layout</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;default&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
35
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> activeMenu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/content/posts&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
36
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> noCache</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
37
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
38
+ <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 &quot;菜单配置&quot;">​</a></h2><p>插件通过 <code>menus</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:#D73A49;--shiki-dark:#F97583;"> type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { AdminPlugin } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@melt-js/libs-bag-entry&#39;</span></span>
39
+ <span class="line"></span>
40
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> contentPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AdminPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
41
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> id: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;content-plugin&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
42
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;内容插件&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
43
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> version: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;1.0.0&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
44
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> menus: [</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;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/content&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
47
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;content.title&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
48
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> icon: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;order&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
49
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sort: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">30</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
50
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> roles: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;authenticated&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
51
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> children: [</span></span>
52
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
53
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/content/posts&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
54
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;content.posts&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
55
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sort: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
56
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> roles: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;authenticated&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
57
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
58
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ]</span></span>
59
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
60
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ]</span></span>
61
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>菜单字段:</p><table tabindex="0"><thead><tr><th>字段</th><th>作用</th></tr></thead><tbody><tr><td><code>path</code></td><td>菜单标识或目标地址,同一菜单树中必须唯一</td></tr><tr><td><code>title</code></td><td>菜单文本或 i18n key</td></tr><tr><td><code>icon</code></td><td>宿主支持的图标名称</td></tr><tr><td><code>sort</code></td><td>同级排序,值越小越靠前</td></tr><tr><td><code>badge</code></td><td>徽标文字,例如 <code>新</code>、<code>HOT</code></td></tr><tr><td><code>hidden</code></td><td>是否隐藏菜单节点</td></tr><tr><td><code>roles</code></td><td>菜单可见角色</td></tr><tr><td><code>permissions</code></td><td>菜单可见权限点</td></tr><tr><td><code>children</code></td><td>子菜单</td></tr></tbody></table><p>父级菜单可以只是分组,不一定对应真实页面。最终叶子菜单的 <code>path</code> 通常应该与路由路径一致。</p><h2 id="一个完整示例" tabindex="-1">一个完整示例 <a class="header-anchor" href="#一个完整示例" aria-label="Permalink to &quot;一个完整示例&quot;">​</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:#D73A49;--shiki-dark:#F97583;"> type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { AdminPlugin } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@melt-js/libs-bag-entry&#39;</span></span>
62
+ <span class="line"></span>
63
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> reportPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AdminPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
64
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> id: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;report-plugin&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
65
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;报表插件&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
66
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> version: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;1.0.0&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
67
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> order: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">20</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
68
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> routes: [</span></span>
69
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
70
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/reports&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
71
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;ReportList&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
72
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> component</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;../views/ReportList.vue&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
73
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> meta: {</span></span>
74
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;report.list&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
75
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> layout: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;default&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
76
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> permissions: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;report.read&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
77
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
78
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
79
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
80
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/reports/:id&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
81
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;ReportDetail&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
82
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> component</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;../views/ReportDetail.vue&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
83
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> meta: {</span></span>
84
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;report.detail&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
85
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> layout: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;default&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
86
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> permissions: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;report.read&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
87
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> activeMenu: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/reports&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
88
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> noCache: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
89
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</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 style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> menus: [</span></span>
93
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
94
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/reports&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
95
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;report.list&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
96
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> icon: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;star&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
97
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sort: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">50</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
98
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> permissions: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;report.read&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</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>
101
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
102
+ <span class="line"></span>
103
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> reportPlugin</span></span></code></pre></div><p>路由与菜单最好使用相同的权限条件。只隐藏菜单不能阻止用户直接输入 URL,真正的页面保护仍由路由守卫负责。</p><h2 id="常见约定" tabindex="-1">常见约定 <a class="header-anchor" href="#常见约定" aria-label="Permalink to &quot;常见约定&quot;">​</a></h2><ul><li>登录、403 等页面使用 <code>layout: &#39;blank&#39;</code> 或不出现在菜单中。</li><li>列表页同时配置路由和菜单。</li><li>详情、编辑页只配置路由,并设置 <code>activeMenu</code>。</li><li>404 通配路由放在宿主路由数组最后。</li><li>路由 <code>name</code>、路由 <code>path</code>、菜单 <code>path</code> 和插件 <code>id</code> 都保持唯一。</li><li>业务页面尽量放到插件中,宿主只保留应用级页面。</li></ul><h2 id="下一步" tabindex="-1">下一步 <a class="header-anchor" href="#下一步" aria-label="Permalink to &quot;下一步&quot;">​</a></h2><p>继续阅读 <a href="./auth-and-permissions.html">登录与权限</a>,为路由和菜单接入真实用户状态。</p>`,31)])])}const c=i(h,[["render",l]]);export{g as __pageData,c as default};
@@ -0,0 +1 @@
1
+ import{_ as i,o as a,c as n,a2 as t}from"./chunks/framework.B3lxS50j.js";const g=JSON.parse('{"title":"路由与菜单","description":"","frontmatter":{},"headers":[],"relativePath":"guide/host/routing-and-menu.md","filePath":"guide/host/routing-and-menu.md","lastUpdated":1794045200000}'),h={name:"guide/host/routing-and-menu.md"};function l(p,s,k,e,E,d){return a(),n("div",null,[...s[0]||(s[0]=[t("",31)])])}const c=i(h,[["render",l]]);export{g as __pageData,c as default};
@@ -0,0 +1,14 @@
1
+ import{_ as i,o as s,c as t,a2 as e}from"./chunks/framework.B3lxS50j.js";const k=JSON.parse('{"title":"项目介绍","description":"","frontmatter":{},"headers":[],"relativePath":"guide/introduction.md","filePath":"guide/introduction.md","lastUpdated":1794045200000}'),l={name:"guide/introduction.md"};function n(p,a,d,h,r,o){return s(),t("div",null,[...a[0]||(a[0]=[e(`<h1 id="项目介绍" tabindex="-1">项目介绍 <a class="header-anchor" href="#项目介绍" aria-label="Permalink to &quot;项目介绍&quot;">​</a></h1><p>Vue-Bag-Admin 是一套面向 Vue 3 中后台项目的插件化开发框架。它把后台应用拆成稳定的宿主和可独立维护的业务插件,让项目可以先快速启动,再随着业务增长逐步拆分。</p><p>如果你第一次接触这个项目,先记住一句话:</p><blockquote><p>宿主负责把应用跑起来,插件负责把业务装进去。</p></blockquote><h2 id="它解决什么问题" tabindex="-1">它解决什么问题 <a class="header-anchor" href="#它解决什么问题" aria-label="Permalink to &quot;它解决什么问题&quot;">​</a></h2><p>普通后台项目通常从一个 <code>src/views</code> 开始。页面少时很直接,业务增加后容易遇到这些问题:</p><ul><li>路由、菜单和权限散落在不同文件中,新增模块要改很多地方。</li><li>商品、订单、系统设置等业务相互引用,很难独立复用。</li><li>多个后台项目需要相同能力时,只能复制代码。</li><li>公共布局、请求和组件不断被业务代码侵入,升级成本越来越高。</li></ul><p>Vue-Bag-Admin 通过宿主与插件分层,把这些职责重新归位:</p><table tabindex="0"><thead><tr><th>层级</th><th>负责什么</th></tr></thead><tbody><tr><td>宿主</td><td>应用初始化、布局、路由守卫、登录态、菜单容器和插件装载</td></tr><tr><td>插件</td><td>业务页面、路由、菜单、多语言和插件初始化</td></tr><tr><td>协议</td><td>统一插件、路由 Meta、菜单、权限、表单 Schema 等数据结构</td></tr><tr><td>基础能力</td><td>HTTP、Fetch、WebSocket、表格、表单和字典组件</td></tr></tbody></table><h2 id="两种使用方式" tabindex="-1">两种使用方式 <a class="header-anchor" href="#两种使用方式" aria-label="Permalink to &quot;两种使用方式&quot;">​</a></h2><h3 id="创建自己的后台项目" tabindex="-1">创建自己的后台项目 <a class="header-anchor" href="#创建自己的后台项目" aria-label="Permalink to &quot;创建自己的后台项目&quot;">​</a></h3><p>这是大多数使用者应该选择的方式。通过脚手架创建一个独立项目:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dlx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @melt-js/libs-bag-create</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> my-admin</span></span></code></pre></div><p>生成后的项目只依赖统一入口包 <code>@melt-js/libs-bag-entry</code>,不需要复制整个 Monorepo。业务可以先写成本地插件,需要跨项目复用时再发布成独立 npm 包。</p><h3 id="开发框架仓库" tabindex="-1">开发框架仓库 <a class="header-anchor" href="#开发框架仓库" aria-label="Permalink to &quot;开发框架仓库&quot;">​</a></h3><p>如果你要修改框架、官方插件或参考后端,可以直接开发当前 Monorepo:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>tpl-vue3-admin-naive-bag 示例宿主</span></span>
2
+ <span class="line"><span>docs-bag 文档站</span></span>
3
+ <span class="line"><span>service-bag-strapi Strapi 参考后端</span></span>
4
+ <span class="line"><span>libs-*/comps-* 框架包、脚手架和官方插件</span></span></code></pre></div><p>这条路线面向框架维护者,不是创建业务项目的前置条件。</p><h2 id="核心运行模型" tabindex="-1">核心运行模型 <a class="header-anchor" href="#核心运行模型" aria-label="Permalink to &quot;核心运行模型&quot;">​</a></h2><p>应用启动时主要发生四件事:</p><ol><li>宿主创建 Vue、Pinia、i18n 和 Router 实例。</li><li>宿主注入认证和请求配置。</li><li><code>bootstrapPlugins()</code> 收集已启用插件,注册路由、菜单和语言包。</li><li><code>HostApp</code> 根据当前路由渲染布局、导航和业务页面。</li></ol><p>插件不是一个特殊的 Vue 应用。它本质上是一个符合 <code>AdminPlugin</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:#D73A49;--shiki-dark:#F97583;"> type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { AdminPlugin } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@melt-js/libs-bag-entry&#39;</span></span>
5
+ <span class="line"></span>
6
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> reportPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AdminPlugin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
7
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> id: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;report-plugin&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
8
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;报表插件&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
9
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> version: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;1.0.0&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
10
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> routes: [],</span></span>
11
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> menus: []</span></span>
12
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
13
+ <span class="line"></span>
14
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> reportPlugin</span></span></code></pre></div><p>因此,本地业务模块和发布到 npm 的插件使用同一套接入方式。</p><h2 id="包的职责" tabindex="-1">包的职责 <a class="header-anchor" href="#包的职责" aria-label="Permalink to &quot;包的职责&quot;">​</a></h2><p>业务项目通常只需要直接安装 <code>@melt-js/libs-bag-entry</code>。它统一导出了下面几层公开能力:</p><table tabindex="0"><thead><tr><th>包</th><th>定位</th></tr></thead><tbody><tr><td><code>@melt-js/libs-bag-core</code></td><td>插件、路由、菜单、权限、字典和表单 Schema 协议</td></tr><tr><td><code>@melt-js/libs-bag-request</code></td><td>HTTP、Fetch、WebSocket 和请求状态控制</td></tr><tr><td><code>@melt-js/libs-bag-ui</code></td><td><code>PmProTable</code>、<code>PmProForm</code>、<code>PmSchemaForm</code> 等组件</td></tr><tr><td><code>@melt-js/libs-bag-host</code></td><td>宿主布局、路由守卫、权限和插件引导</td></tr><tr><td><code>@melt-js/libs-bag-entry</code></td><td>面向业务项目的统一入口</td></tr><tr><td><code>@melt-js/libs-bag-create</code></td><td>创建独立宿主项目的脚手架</td></tr><tr><td><code>@melt-js/comps-bag-*</code></td><td>可选的独立业务插件</td></tr></tbody></table><p>除非你在维护底层分包,否则业务代码建议统一从 <code>@melt-js/libs-bag-entry</code> 导入,避免项目中出现多套运行时入口。</p><h2 id="技术栈与边界" tabindex="-1">技术栈与边界 <a class="header-anchor" href="#技术栈与边界" aria-label="Permalink to &quot;技术栈与边界&quot;">​</a></h2><p>前端运行时基于 Vue 3.5、Vite 6、TypeScript、Vue Router 4、Pinia、Vue I18n、Naive UI 和 Tailwind CSS。</p><p>仓库同时提供 Strapi 5 与 MySQL 参考后端,但前端并不绑定 Strapi。只要认证接口能够返回 token、用户角色和权限点,就可以接入 Java、Go、PHP 或其他后端。</p><p>Vue-Bag-Admin 更适合:</p><ul><li>有多个业务域、需要长期演进的中后台。</li><li>希望在多个后台项目之间复用业务模块。</li><li>想统一路由、菜单、权限和页面搭建方式的团队。</li></ul><p>如果项目只有少量固定页面,并且不会复用或扩展,直接使用 Vue Router 和组件库可能更简单。</p><h2 id="推荐阅读顺序" tabindex="-1">推荐阅读顺序 <a class="header-anchor" href="#推荐阅读顺序" aria-label="Permalink to &quot;推荐阅读顺序&quot;">​</a></h2><p>第一次使用时,按这条链路阅读即可:</p><ol><li><a href="./getting-started.html">快速上手</a></li><li><a href="./create-project.html">创建项目</a></li><li><a href="./host/bootstrap.html">初始化宿主</a></li><li><a href="./host/routing-and-menu.html">路由与菜单</a></li><li><a href="./host/auth-and-permissions.html">登录与权限</a></li><li><a href="./request-and-components.html">请求与组件</a></li></ol><p>完成主线后,可以按目标继续阅读:</p><ul><li>安装现有能力:<a href="./official-plugins/">官方插件</a></li><li>开发业务扩展:<a href="./plugins/create-plugin.html">插件开发</a></li></ul>`,39)])])}const u=i(l,[["render",n]]);export{k as __pageData,u as default};
@@ -0,0 +1 @@
1
+ import{_ as i,o as s,c as t,a2 as e}from"./chunks/framework.B3lxS50j.js";const k=JSON.parse('{"title":"项目介绍","description":"","frontmatter":{},"headers":[],"relativePath":"guide/introduction.md","filePath":"guide/introduction.md","lastUpdated":1794045200000}'),l={name:"guide/introduction.md"};function n(p,a,d,h,r,o){return s(),t("div",null,[...a[0]||(a[0]=[e("",39)])])}const u=i(l,[["render",n]]);export{k as __pageData,u as default};
@@ -0,0 +1,15 @@
1
+ import{_ as a,o as i,c as e,a2 as l}from"./chunks/framework.B3lxS50j.js";const k=JSON.parse('{"title":"本地联调","description":"","frontmatter":{},"headers":[],"relativePath":"guide/local-debugging.md","filePath":"guide/local-debugging.md","lastUpdated":1794045200000}'),t={name:"guide/local-debugging.md"};function n(p,s,h,o,d,c){return i(),e("div",null,[...s[0]||(s[0]=[l(`<h1 id="本地联调" tabindex="-1">本地联调 <a class="header-anchor" href="#本地联调" aria-label="Permalink to &quot;本地联调&quot;">​</a></h1><p>本地联调主要就两种情况:</p><ul><li>在当前 Monorepo 里,怎么联调 <code>tpl-vue3-admin-naive-bag</code> 和 <code>libs-*</code> / <code>comps-*</code></li><li>在仓库外新建一个使用方项目后,怎么通过 <code>link:</code> 联调主包和插件包</li></ul><p>如果你最近主要在改 <code>@melt-js/libs-bag-entry</code>、<code>@melt-js/comps-bag-shop</code>、<code>@melt-js/comps-bag-sys</code>,直接看这页就行。</p><p>如果你是从“快速上手”跳过来的,这页主要讲两件事:参与仓库开发,或者在外部使用方项目里联调本地包。</p><h2 id="两种联调方式" tabindex="-1">两种联调方式 <a class="header-anchor" href="#两种联调方式" aria-label="Permalink to &quot;两种联调方式&quot;">​</a></h2><p>常用的联调路线有两条:</p><ol><li>仓库内联调:直接跑 <code>tpl-vue3-admin-naive-bag</code></li><li>外部项目联调:在一个独立使用方项目里通过 <code>link:</code> 安装本地包</li></ol><p>前者适合改框架内部,后者适合模拟真实使用方。</p><h2 id="方式一-仓库内联调" tabindex="-1">方式一:仓库内联调 <a class="header-anchor" href="#方式一-仓库内联调" aria-label="Permalink to &quot;方式一:仓库内联调&quot;">​</a></h2><h3 id="_1-安装根依赖" tabindex="-1">1. 安装根依赖 <a class="header-anchor" href="#_1-安装根依赖" aria-label="Permalink to &quot;1. 安装根依赖&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> install</span></span></code></pre></div><h3 id="_2-启动宿主示例" tabindex="-1">2. 启动宿主示例 <a class="header-anchor" href="#_2-启动宿主示例" aria-label="Permalink to &quot;2. 启动宿主示例&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --filter</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @melt-js/tpl-vue3-admin-naive-bag</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span></span></code></pre></div><p><code>tpl-vue3-admin-naive-bag</code> 直接吃 Monorepo 里的源码,适合调这些东西:</p><ul><li>宿主布局</li><li>权限与标签页</li><li>插件协议</li><li><code>@melt-js/libs-bag-ui</code> 组件</li><li><code>@melt-js/libs-bag-request</code> 请求能力</li></ul><p>仓库内联调要保证运行时入口同源。<code>tpl-vue3-admin-naive-bag</code> 会把 <code>@melt-js/libs-bag-entry</code>、<code>@melt-js/libs-bag-core</code>、<code>@melt-js/libs-bag-host</code>、<code>@melt-js/libs-bag-request</code>、<code>@melt-js/libs-bag-ui</code> 和官方插件都 alias 到当前仓库源码。这样宿主启动时 <code>bootstrapPlugins()</code> 注册插件,插件管理页再调用 <code>listRuntimePlugins()</code> 时,读到的是同一份 runtime registry。</p><p>如果只 alias 了 <code>@melt-js/libs-bag-core</code> / <code>@melt-js/libs-bag-host</code>,但插件页面从另一个 <code>@melt-js/libs-bag-entry</code> 包实例导入 API,就会出现“菜单已经有插件页面,但插件管理页识别到 0 个插件”的情况。</p><h3 id="_3-后端联调-可选" tabindex="-1">3. 后端联调(可选) <a class="header-anchor" href="#_3-后端联调-可选" aria-label="Permalink to &quot;3. 后端联调(可选)&quot;">​</a></h3><p>如果你还要把仓库里的 Strapi 一起跑起来:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> service-bag-strapi</span></span>
2
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span></span></code></pre></div><p>这条路线的特点是改完就能看,不用先打包再喂给外部项目。</p><h2 id="方式二-外部使用方项目联调" tabindex="-1">方式二:外部使用方项目联调 <a class="header-anchor" href="#方式二-外部使用方项目联调" aria-label="Permalink to &quot;方式二:外部使用方项目联调&quot;">​</a></h2><p>如果你想看真实使用方会遇到什么,最好单独建个测试项目,再用 <code>link:</code> 挂本地包。</p><h2 id="典型目录结构" tabindex="-1">典型目录结构 <a class="header-anchor" href="#典型目录结构" aria-label="Permalink to &quot;典型目录结构&quot;">​</a></h2><p>例如:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>E:\\wwwsite\\hel-components</span></span>
3
+ <span class="line"><span>E:\\web_test_loca\\loca_test</span></span></code></pre></div><p>其中:</p><ul><li><code>hel-components</code> 是框架仓库</li><li><code>loca_test</code> 是外部使用方项目</li></ul><h2 id="使用方装哪些包" tabindex="-1">使用方装哪些包 <a class="header-anchor" href="#使用方装哪些包" aria-label="Permalink to &quot;使用方装哪些包&quot;">​</a></h2><p>最小联调组合是:</p><ul><li><code>@melt-js/libs-bag-entry</code></li><li><code>@melt-js/comps-bag-shop</code></li><li><code>@melt-js/comps-bag-sys</code></li></ul><p>也就是说,默认就是“一个主包 + 按需插件包”,不用把底层拆包都扔给使用方。</p><h2 id="使用方-package-json-示例" tabindex="-1">使用方 package.json 示例 <a class="header-anchor" href="#使用方-package-json-示例" aria-label="Permalink to &quot;使用方 package.json 示例&quot;">​</a></h2><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
4
+ <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;dependencies&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
5
+ <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;@melt-js/libs-bag-entry&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;link:../../wwwsite/hel-components/libs-bag-entry&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
6
+ <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;@melt-js/comps-bag-shop&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;link:../../wwwsite/hel-components/comps-bag-shop&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
7
+ <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> &quot;@melt-js/comps-bag-sys&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;link:../../wwwsite/hel-components/comps-bag-sys&quot;</span></span>
8
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
9
+ <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 &quot;联调时先记住一件事&quot;">​</a></h2><p>外部使用方吃的是包目录里的构建产物,不是你仓库里的实时源码。</p><p>所以顺序别弄反:</p><ol><li>先在框架仓库里构建包</li><li>再去使用方项目安装依赖</li><li>再启动使用方项目</li></ol><h2 id="执行顺序" tabindex="-1">执行顺序 <a class="header-anchor" href="#执行顺序" aria-label="Permalink to &quot;执行顺序&quot;">​</a></h2><h3 id="第一步-在框架仓库里构建" tabindex="-1">第一步:在框架仓库里构建 <a class="header-anchor" href="#第一步-在框架仓库里构建" aria-label="Permalink to &quot;第一步:在框架仓库里构建&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> E:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\\w</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">wwsite</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\\h</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">el-components</span></span>
10
+ <span class="line"></span>
11
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --filter</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @melt-js/libs-bag-entry</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> build</span></span>
12
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --filter</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @melt-js/comps-bag-shop</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> build</span></span>
13
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --filter</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @melt-js/comps-bag-sys</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> build</span></span></code></pre></div><h3 id="第二步-在使用方项目里安装" tabindex="-1">第二步:在使用方项目里安装 <a class="header-anchor" href="#第二步-在使用方项目里安装" aria-label="Permalink to &quot;第二步:在使用方项目里安装&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> E:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\\w</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">eb_test_loca</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\\l</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">oca_test</span></span>
14
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> install</span></span></code></pre></div><h3 id="第三步-启动使用方项目" tabindex="-1">第三步:启动使用方项目 <a class="header-anchor" href="#第三步-启动使用方项目" aria-label="Permalink to &quot;第三步:启动使用方项目&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span></span></code></pre></div><h2 id="什么时候需要重新-build" tabindex="-1">什么时候需要重新 build <a class="header-anchor" href="#什么时候需要重新-build" aria-label="Permalink to &quot;什么时候需要重新 build&quot;">​</a></h2><p>只要你改了这些目录里的内容,基本都要重新构建一次:</p><ul><li><code>libs-bag-core</code></li><li><code>libs-bag-request</code></li><li><code>libs-bag-ui</code></li><li><code>libs-bag-host</code></li><li><code>libs-bag-entry</code></li><li><code>comps-bag-shop</code></li><li><code>comps-bag-sys</code></li></ul><p>尤其是宿主布局、导出入口、插件路由、样式和 i18n 这几块,外部项目一般都得重新吃一遍新的 <code>dist</code>。</p><h2 id="样式联调要注意什么" tabindex="-1">样式联调要注意什么 <a class="header-anchor" href="#样式联调要注意什么" aria-label="Permalink to &quot;样式联调要注意什么&quot;">​</a></h2><p>外部项目联调里,很多样式问题不是 JS 本身导致的,而是扫描范围和引入顺序出了问题。</p><p>先检查这两件事:</p><ol><li>Tailwind <code>content</code> 是否扫描到了链接包的 <code>dist</code></li><li>样式引入顺序是否是“先库样式,再项目本地样式”</li></ol><p>常见写法:</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:#032F62;--shiki-dark:#9ECBFF;"> &#39;@melt-js/libs-bag-entry/style.css&#39;</span></span>
15
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./style.css&#39;</span></span></code></pre></div><p>顺序反了,或者扫描不到链接包里的类名,常见现象就是图标大小不对、响应式类失效,布局和按钮样式跟着乱。</p><h2 id="常见问题" tabindex="-1">常见问题 <a class="header-anchor" href="#常见问题" aria-label="Permalink to &quot;常见问题&quot;">​</a></h2><h3 id="_1-我改了源码-使用方没变化" tabindex="-1">1. 我改了源码,使用方没变化 <a class="header-anchor" href="#_1-我改了源码-使用方没变化" aria-label="Permalink to &quot;1. 我改了源码,使用方没变化&quot;">​</a></h3><p>先确认你改的是不是包源码,然后重新执行一遍:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --filter</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @melt-js/libs-bag-entry</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> build</span></span></code></pre></div><p>如果还涉及插件,再把插件也重构建一遍。</p><h3 id="_2-使用方启动时报依赖解析错误" tabindex="-1">2. 使用方启动时报依赖解析错误 <a class="header-anchor" href="#_2-使用方启动时报依赖解析错误" aria-label="Permalink to &quot;2. 使用方启动时报依赖解析错误&quot;">​</a></h3><p>先检查:</p><ul><li><code>link:</code> 路径是否写对</li><li>对应包是否已经生成 <code>dist</code></li><li>使用方是否重新执行过 <code>pnpm install</code></li></ul><h3 id="_3-使用方页面样式丢失" tabindex="-1">3. 使用方页面样式丢失 <a class="header-anchor" href="#_3-使用方页面样式丢失" aria-label="Permalink to &quot;3. 使用方页面样式丢失&quot;">​</a></h3><p>优先排查:</p><ul><li>Tailwind 扫描范围</li><li><code>@melt-js/libs-bag-entry/style.css</code> 是否已引入</li><li>本地样式是否覆盖顺序正确</li></ul><h3 id="_4-使用方控制台出现-i18n-缺词条-warning" tabindex="-1">4. 使用方控制台出现 i18n 缺词条 warning <a class="header-anchor" href="#_4-使用方控制台出现-i18n-缺词条-warning" aria-label="Permalink to &quot;4. 使用方控制台出现 i18n 缺词条 warning&quot;">​</a></h3><p>先看路由或菜单标题是不是把中文直接当 key 丢进宿主了。</p><p>如果你传的是 <code>shop.order.list</code> 这种 key,但文案没补齐,宿主现在会先回退原值,不会一直刷 warning;不过更稳的做法还是把插件自己的词条补进语言包。</p><h2 id="什么时候选哪种联调方式" tabindex="-1">什么时候选哪种联调方式 <a class="header-anchor" href="#什么时候选哪种联调方式" aria-label="Permalink to &quot;什么时候选哪种联调方式&quot;">​</a></h2><ul><li>你在改框架内部实现:优先用仓库内联调</li><li>你在验证 npm 使用方接入姿势:优先用外部项目联调</li><li>你在排查软连接、样式、peerDependencies 问题:一定要用外部项目联调</li></ul><p>这两种方式不冲突。平时可以先在仓库里改,再去外部项目做一遍真实接入验证。</p>`,74)])])}const g=a(t,[["render",n]]);export{k as __pageData,g as default};
@@ -0,0 +1 @@
1
+ import{_ as a,o as i,c as e,a2 as l}from"./chunks/framework.B3lxS50j.js";const k=JSON.parse('{"title":"本地联调","description":"","frontmatter":{},"headers":[],"relativePath":"guide/local-debugging.md","filePath":"guide/local-debugging.md","lastUpdated":1794045200000}'),t={name:"guide/local-debugging.md"};function n(p,s,h,o,d,c){return i(),e("div",null,[...s[0]||(s[0]=[l("",74)])])}const g=a(t,[["render",n]]);export{k as __pageData,g as default};