@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,250 @@
|
|
|
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>插件化开发 | 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_plugin-development.md.BQzTwLRr.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_plugin-development" data-v-39a288b8><div><h1 id="插件化开发" tabindex="-1">插件化开发 <a class="header-anchor" href="#插件化开发" aria-label="Permalink to "插件化开发""></a></h1><p>Vue-Bag-Admin 把应用拆成两块,宿主应用负责跑起来,业务插件负责放页面和配置。相对独立的业务域,放进 <code>comps-bag-*</code> 包里会更好维护。</p><p>如果你准备把插件单独发到 npm,这篇可以直接当起点。仓库里的插件包已经按发布形态收过一轮,新插件照这个结构走,后面少补很多边角。</p><h2 id="插件能提供什么" tabindex="-1">插件能提供什么 <a class="header-anchor" href="#插件能提供什么" aria-label="Permalink to "插件能提供什么""></a></h2><p>一个插件通常会带这些东西:</p><ul><li>业务页面组件</li><li>路由定义</li><li>菜单定义</li><li>多语言词条</li><li>初始化安装钩子</li><li>权限点声明</li><li>插件配置项声明</li><li>扩展点贡献</li><li>插件元信息(启用状态、顺序、依赖)</li></ul><h2 id="adminplugin-结构" tabindex="-1">AdminPlugin 结构 <a class="header-anchor" href="#adminplugin-结构" aria-label="Permalink to "AdminPlugin 结构""></a></h2><p>当前插件接口除了基础的 <code>id</code>、<code>name</code>、<code>version</code> 外,还支持这些元信息:</p><ul><li><code>enabled</code>:是否默认启用,设为 <code>false</code> 时不会注册</li><li><code>order</code>:插件排序,值越小越先注册</li><li><code>dependsOn</code>:依赖的插件 <code>id</code> 列表</li><li><code>routes</code>:插件提供的路由</li><li><code>menus</code>:插件提供的菜单</li><li><code>locales</code>:插件提供的语言包</li><li><code>permissions</code>:插件声明的权限点,宿主可以汇总到角色/权限后台</li><li><code>settings</code>:插件声明的配置项,宿主可以生成插件配置页</li><li><code>contributes</code>:插件贡献到宿主扩展点的能力,例如快捷入口、工具栏动作、卡片等</li><li><code>compatibility</code>:插件声明的宿主或 Vue 版本兼容范围</li><li><code>install</code>:安装钩子,能拿到 <code>app</code>、<code>router</code> 和当前已启用插件列表</li><li><code>dispose</code>:卸载或应用重引导前的清理钩子</li></ul><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;"> '@melt-js/libs-bag-core'</span></span>
|
|
22
|
+
<span class="line"></span>
|
|
23
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> plugin</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>
|
|
24
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> id: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'plugin-report'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
25
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'报表插件'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
26
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> version: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'1.0.0'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</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;"> order: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">20</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
29
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> dependsOn: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'plugin-shop'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
30
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> routes: [],</span></span>
|
|
31
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> menus: [],</span></span>
|
|
32
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> locales: {},</span></span>
|
|
33
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> permissions: [</span></span>
|
|
34
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { code: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.read'</span><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;">, group: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'报表'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
35
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { code: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.export'</span><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;">, group: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'报表'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
36
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ],</span></span>
|
|
37
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> settings: [</span></span>
|
|
38
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
39
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> field: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'defaultRange'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
40
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> label: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'默认统计周期'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
41
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> component: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'select'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
42
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> defaultValue: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'7d'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
43
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> options: [</span></span>
|
|
44
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { label: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'最近 7 天'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, value: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'7d'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
45
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { label: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'最近 30 天'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, value: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'30d'</span><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;"> }</span></span>
|
|
48
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ],</span></span>
|
|
49
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> contributes: {</span></span>
|
|
50
|
+
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'dashboard.widgets'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [{ key: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report-summary'</span><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>
|
|
51
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
52
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> install</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">app</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">context</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;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(context.enabledPluginIds)</span></span>
|
|
54
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
55
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> dispose</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">context</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
56
|
+
<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;">'dispose'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, context.enabledPluginIds)</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>
|
|
60
|
+
<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;"> plugin</span></span></code></pre></div><p>插件上下文中的 <code>enabledPluginIds</code> 表示当前已经通过启用过滤、依赖校验和冲突校验的插件列表,适合用来做跨插件联动。</p><h2 id="插件启停状态" tabindex="-1">插件启停状态 <a class="header-anchor" href="#插件启停状态" aria-label="Permalink to "插件启停状态""></a></h2><p>默认情况下,插件启停状态会写入浏览器本地存储,够本地开发和演示使用。生产环境如果要按租户、角色、环境或后端配置控制插件启停,可以在宿主启动时注入 <code>pluginStateProvider</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;">await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> bootstrapPlugins</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
61
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> app,</span></span>
|
|
62
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> router,</span></span>
|
|
63
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> plugins,</span></span>
|
|
64
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> pluginStateProvider: {</span></span>
|
|
65
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getDisabledPluginIds</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;"> tenantConfig.disabledPluginIds,</span></span>
|
|
66
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setPluginEnabledState</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">pluginId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">enabled</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>
|
|
67
|
+
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 可以在这里调用后端接口,或者写入你的配置中心。</span></span>
|
|
68
|
+
<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;">(pluginId, enabled)</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;"> }</span></span>
|
|
71
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre></div><p>这样插件管理页、菜单和路由注册会读同一份状态。</p><h2 id="路由与菜单协议" tabindex="-1">路由与菜单协议 <a class="header-anchor" href="#路由与菜单协议" aria-label="Permalink to "路由与菜单协议""></a></h2><p>插件里的 <code>routes</code> 和 <code>menus</code> 都有一层框架约定,定义时尽量一次写清楚。</p><h3 id="路由-meta" tabindex="-1">路由 meta <a class="header-anchor" href="#路由-meta" aria-label="Permalink to "路由 meta""></a></h3><p>插件路由使用的是 <code>AdminRouteRecordRaw</code>,常用的 <code>meta</code> 字段包括:</p><ul><li><code>title</code>:页面标题,通常写 i18n key</li><li><code>layout</code>:布局名,默认后台页一般使用 <code>default</code></li><li><code>roles</code>:角色访问控制</li><li><code>permissions</code>:权限点访问控制</li><li><code>public</code>:是否是公开页面</li><li><code>hidden</code>:是否从菜单和标签页等导航区域隐藏</li><li><code>activeMenu</code>:当前页高亮归属的菜单路径,详情页和编辑页建议显式声明</li><li><code>noCache</code>:是否跳过标签缓存</li></ul><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>
|
|
72
|
+
<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;">'/report/detail/:id'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
73
|
+
<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;">'ReportDetail'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
74
|
+
<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;">=></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;">'./views/ReportDetail.vue'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
75
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> meta</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
76
|
+
<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;">'report.detail'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
77
|
+
<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;">'default'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
78
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> roles</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'authenticated'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
79
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> permissions</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.read'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
80
|
+
<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;">'/report/list'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
81
|
+
<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 style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
82
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> hidden</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
|
|
83
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
84
|
+
<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><p>插件菜单使用 <code>MenuConfig</code>,除了基础的 <code>path</code>、<code>title</code>、<code>icon</code>、<code>sort</code> 外,还支持:</p><ul><li><code>hidden</code>:隐藏菜单项,但仍可保留路由能力</li><li><code>badge</code>:菜单徽标,例如 <code>New</code>、<code>HOT</code> 或数字</li><li><code>roles</code>:角色级菜单可见性</li><li><code>permissions</code>:权限点级菜单可见性</li><li><code>children</code>:子菜单配置</li></ul><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:#6F42C1;--shiki-dark:#B392F0;">menus</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [</span></span>
|
|
85
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
86
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/report'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
87
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.title'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
88
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> icon: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'chart'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
89
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sort: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">80</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
90
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> children: [</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;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/report/list'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
93
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.list'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
94
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> permissions: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.read'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
|
|
95
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
96
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ]</span></span>
|
|
97
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
98
|
+
<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><h3 id="_1-新建目录" tabindex="-1">1. 新建目录 <a class="header-anchor" href="#_1-新建目录" aria-label="Permalink to "1. 新建目录""></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;">mkdir</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> comps-bag-report/src/views</span></span></code></pre></div><h3 id="_2-配置-package-json" tabindex="-1">2. 配置 package.json <a class="header-anchor" href="#_2-配置-package-json" aria-label="Permalink to "2. 配置 package.json""></a></h3><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>
|
|
99
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "name"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"@melt-js/comps-bag-report"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
100
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "version"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"0.1.0"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
101
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "type"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"module"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
102
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "files"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"dist"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
103
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "main"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"./dist/index.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
104
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "module"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"./dist/index.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
105
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "types"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"./dist/index.d.ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
106
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "exports"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
107
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "."</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
108
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "types"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"./dist/index.d.ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
109
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "import"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"./dist/index.js"</span></span>
|
|
110
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
111
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
112
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "sideEffects"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
113
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "peerDependencies"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
114
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "vue"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"^3.5.0"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
115
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "vue-router"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"^4.4.0"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
116
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "@melt-js/libs-bag-core"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"^0.1.0"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
117
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "@melt-js/libs-bag-ui"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"^0.1.0"</span></span>
|
|
118
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
119
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "devDependencies"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
120
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "vue"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"^3.5.0"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
121
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "vue-router"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"^4.4.0"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
122
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "@melt-js/libs-bag-core"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"workspace:*"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
123
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "@melt-js/libs-bag-ui"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"workspace:*"</span></span>
|
|
124
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
125
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "scripts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
126
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "build"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"vite build && vue-tsc --project tsconfig.build.json --emitDeclarationOnly"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
127
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "check-types"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"vue-tsc --noEmit"</span></span>
|
|
128
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
129
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>这份配置按“真的要发到 npm”来写:</p><ul><li><code>peerDependencies</code> 声明宿主必须提供的运行时依赖,避免外部项目装出多份 <code>vue</code></li><li><code>devDependencies</code> 里的 <code>workspace:*</code> 方便你在 Monorepo 内联调</li><li><code>main / module / types / exports</code> 都指向 <code>dist</code>,而不是源码目录</li></ul><p>临时试验可以先简单点。只要准备长期维护,最好一开始就按这套口径写。</p><h3 id="_3-编写页面" tabindex="-1">3. 编写页面 <a class="header-anchor" href="#_3-编写页面" aria-label="Permalink to "3. 编写页面""></a></h3><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;"><</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
130
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> class</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"p-6 bg-white rounded shadow-sm"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
131
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">h2</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> class</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"text-2xl font-bold mb-4"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">>报表中心</</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">h2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
132
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">p</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">>这是一个通过插件接入的业务页面。</</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">p</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
133
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</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 style="--shiki-light:#22863A;--shiki-dark:#85E89D;">template</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span></code></pre></div><h3 id="_4-导出插件定义" tabindex="-1">4. 导出插件定义 <a class="header-anchor" href="#_4-导出插件定义" aria-label="Permalink to "4. 导出插件定义""></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:#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;"> '@melt-js/libs-bag-core'</span></span>
|
|
135
|
+
<span class="line"></span>
|
|
136
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> plugin</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>
|
|
137
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> id: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'plugin-report'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
138
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'报表插件'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
139
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> version: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'1.0.0'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
140
|
+
<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>
|
|
141
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> routes: [</span></span>
|
|
142
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
143
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/report/list'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
144
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'ReportList'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
145
|
+
<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;">=></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;">'./views/ReportList.vue'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
146
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> meta: {</span></span>
|
|
147
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.list'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
148
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> layout: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'default'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
149
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> roles: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'authenticated'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
150
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> permissions: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.read'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
|
|
151
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</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 style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/report/detail/:id'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
155
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'ReportDetail'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
156
|
+
<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;">=></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;">'./views/ReportDetail.vue'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
157
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> meta: {</span></span>
|
|
158
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.detail'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
159
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> layout: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'default'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
160
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> roles: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'authenticated'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
161
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> permissions: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.read'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
162
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> activeMenu: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/report/list'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
163
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> noCache: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
164
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> hidden: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
|
|
165
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
166
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
167
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ],</span></span>
|
|
168
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> menus: [</span></span>
|
|
169
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
170
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/report'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
171
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.title'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
172
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> icon: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'chart'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
173
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sort: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">80</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
174
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> roles: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'authenticated'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
175
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> children: [</span></span>
|
|
176
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
177
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/report/list'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
178
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.list'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
179
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> permissions: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'report.read'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
|
|
180
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
181
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ]</span></span>
|
|
182
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
183
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ],</span></span>
|
|
184
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> locales: {</span></span>
|
|
185
|
+
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'zh-CN'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
186
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> report: {</span></span>
|
|
187
|
+
<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>
|
|
188
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> list: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'报表中心'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
189
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> detail: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'报表详情'</span></span>
|
|
190
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
191
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
192
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> en: {</span></span>
|
|
193
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> report: {</span></span>
|
|
194
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'Reports'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
195
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> list: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'Reports'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
196
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> detail: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'Report Detail'</span></span>
|
|
197
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
198
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
199
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
200
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
201
|
+
<span class="line"></span>
|
|
202
|
+
<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;"> plugin</span></span></code></pre></div><h3 id="_5-增加构建配置" tabindex="-1">5. 增加构建配置 <a class="header-anchor" href="#_5-增加构建配置" aria-label="Permalink to "5. 增加构建配置""></a></h3><p>如果你的插件准备发布到 npm,至少再补两份文件:</p><p><code>tsconfig.build.json</code></p><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>
|
|
203
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "extends"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"./tsconfig.json"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
204
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "compilerOptions"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
205
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "declaration"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
206
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "emitDeclarationOnly"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
207
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "outDir"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"dist"</span></span>
|
|
208
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
209
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "include"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"src/**/*.ts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"src/**/*.vue"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
|
|
210
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p><code>vite.config.mjs</code></p><div class="language-js vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">js</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;"> { defineConfig } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'vite'</span></span>
|
|
211
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> vue </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@vitejs/plugin-vue'</span></span>
|
|
212
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { resolve } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'node:path'</span></span>
|
|
213
|
+
<span class="line"></span>
|
|
214
|
+
<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:#6F42C1;--shiki-dark:#B392F0;"> defineConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
215
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> plugins: [</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">vue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()],</span></span>
|
|
216
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> build: {</span></span>
|
|
217
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> lib: {</span></span>
|
|
218
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> entry: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">resolve</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(process.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">cwd</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(), </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'src/index.ts'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
219
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> formats: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'es'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
220
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> fileName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'index.js'</span></span>
|
|
221
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
222
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> rollupOptions: {</span></span>
|
|
223
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> external: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'vue'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'vue-router'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'@melt-js/libs-bag-core'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'@melt-js/libs-bag-ui'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
|
|
224
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
225
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
226
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre></div><p>这样处理后,插件包的使用者拿到的是明确的 <code>dist</code> 产物,宿主消费起来也更稳。</p><h2 id="在宿主中挂载" tabindex="-1">在宿主中挂载 <a class="header-anchor" href="#在宿主中挂载" aria-label="Permalink to "在宿主中挂载""></a></h2><p>在宿主应用里引入并传给 <code>bootstrapPlugins()</code>。如果你是从脚手架生成项目,一般会在 <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;"> 'vue'</span></span>
|
|
227
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> reportPlugin </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/comps-bag-report'</span></span>
|
|
228
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { bootstrapPlugins } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-host'</span></span>
|
|
229
|
+
<span class="line"></span>
|
|
230
|
+
<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>
|
|
231
|
+
<span class="line"></span>
|
|
232
|
+
<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>
|
|
233
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> app,</span></span>
|
|
234
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> router,</span></span>
|
|
235
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i18n,</span></span>
|
|
236
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> plugins: [reportPlugin]</span></span>
|
|
237
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre></div><p>如果你是在当前仓库里联调,也可以参考示例宿主 <code>tpl-vue3-admin-naive-bag/src/main.ts</code> 的接入方式。</p><h2 id="插件注册规则" tabindex="-1">插件注册规则 <a class="header-anchor" href="#插件注册规则" aria-label="Permalink to "插件注册规则""></a></h2><p>宿主注册插件时会走这几步:</p><ol><li>按 <code>order</code> 升序排序</li><li>基于 <code>enabled</code> 与本地禁用列表过滤插件</li><li>校验 <code>dependsOn</code> 依赖是否已在启用插件集合中</li><li>对启用插件集合执行冲突校验</li><li>注册路由、菜单和多语言</li><li>执行插件 <code>install</code> 钩子</li></ol><h2 id="冲突检测" tabindex="-1">冲突检测 <a class="header-anchor" href="#冲突检测" aria-label="Permalink to "冲突检测""></a></h2><p>当前内置了这些冲突保护,校验范围覆盖“已启用的插件集合”和宿主已经注册的基础路由:</p><ul><li>重复插件 <code>id</code></li><li>重复路由 <code>path</code></li><li>重复路由 <code>name</code></li><li>重复菜单 <code>path</code></li></ul><p>一旦冲突,启动阶段会直接抛错,不会静默覆盖。</p><h2 id="插件启用与禁用" tabindex="-1">插件启用与禁用 <a class="header-anchor" href="#插件启用与禁用" aria-label="Permalink to "插件启用与禁用""></a></h2><p>插件是否启用由两层共同决定:</p><ul><li>插件自身的 <code>enabled</code></li><li>宿主本地存储中的禁用插件列表</li></ul><p>也就是说,你可以保留插件代码,只在运行时禁用它,不必删除依赖。</p><p>当前禁用状态持久化在浏览器本地存储中,默认存储键为 <code>bag.admin.disabledPlugins</code>。如果你要做插件管理页,可以直接围绕这个运行时语义去设计启停逻辑。</p><p>这里容易踩坑:插件启停会影响路由、菜单和依赖关系。切换状态后,通常要重新执行一次应用引导流程,或者刷新后再生效。</p><p>如果你要在界面层做插件管理中心,可以直接复用 <code>@melt-js/libs-bag-entry</code> 暴露的运行时 API:</p><blockquote><p>本地联调时要留心:插件页面、宿主入口和 <code>bootstrapPlugins()</code> 必须从同一个运行时入口拿 API。业务项目最好都从 <code>@melt-js/libs-bag-entry</code> 导入;如果 Vite alias 把插件源码接进来了,也要把 <code>@melt-js/libs-bag-entry</code> alias 到当前仓库的 <code>libs-bag-entry/src/index.ts</code>,不然会出现插件已经注册、管理页却读到空列表的情况。</p></blockquote><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;"> { listRuntimePlugins, setPluginEnabledState } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '@melt-js/libs-bag-entry'</span></span>
|
|
238
|
+
<span class="line"></span>
|
|
239
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> plugins</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> listRuntimePlugins</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
240
|
+
<span class="line"></span>
|
|
241
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setPluginEnabledState</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'plugin-shop'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
242
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">window.location.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">reload</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div><p><code>listRuntimePlugins()</code> 会返回当前宿主注册过的插件清单,以及启用状态、依赖信息、路由数量、菜单数量、权限点数量、设置项数量和贡献点数量,管理页可以直接拿来渲染。</p><h2 id="开发态与发布态的区别" tabindex="-1">开发态与发布态的区别 <a class="header-anchor" href="#开发态与发布态的区别" aria-label="Permalink to "开发态与发布态的区别""></a></h2><p>刚拆包时这里很容易弄混,单独说一下:</p><ul><li>开发态:更关心 Monorepo 内联调,允许使用 <code>workspace:*</code></li><li>发布态:更关心外部项目消费,入口应统一指向 <code>dist</code></li></ul><p>更稳的做法是:</p><ul><li>在仓库里开发时,通过 workspace 依赖做源码联调</li><li>对外发布时,让 npm 消费者只接触 <code>dist</code>、<code>exports</code> 和 <code>peerDependencies</code></li></ul><p>这样既方便仓库内部开发,也不会把工作区里的临时写法带到公开包里。</p><h2 id="install-钩子" tabindex="-1">install 钩子 <a class="header-anchor" href="#install-钩子" aria-label="Permalink to "install 钩子""></a></h2><p><code>install(app, context)</code> 适合做以下事情:</p><ul><li>注册全局组件</li><li>注册布局</li><li>注入全局配置</li><li>根据 <code>enabledPluginIds</code> 做跨插件联动</li></ul><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:#6F42C1;--shiki-dark:#B392F0;">install</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(app, context) {</span></span>
|
|
243
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (context.enabledPluginIds.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">includes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'plugin-shop'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)) {</span></span>
|
|
244
|
+
<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;">'商城插件已启用'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
245
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
246
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div></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>
|
|
247
|
+
<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>
|
|
248
|
+
|
|
249
|
+
</body>
|
|
250
|
+
</html>
|