@done-coding/admin-core 0.8.3-alpha.0 → 0.9.1-alpha.0
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/docs/nested-config-paradigm.md +80 -0
- package/es/bridge/config-hook.mjs +37 -0
- package/es/bridge/index.mjs +157 -62
- package/es/bridge/plugin.mjs +29 -0
- package/es/bridge/theme.mjs +65 -0
- package/es/components/app-layout/AppBody.vue.mjs +1 -1
- package/es/components/app-layout/AppBody.vue2.mjs +47 -49
- package/es/components/app-layout/AppBreadcrumb.vue.mjs +1 -1
- package/es/components/app-layout/AppBreadcrumb.vue2.mjs +35 -41
- package/es/components/app-layout/AppFooter.vue.mjs +2 -2
- package/es/components/app-layout/AppFooter.vue2.mjs +8 -8
- package/es/components/app-layout/AppHeader.vue.mjs +1 -1
- package/es/components/app-layout/AppHeader.vue2.mjs +60 -69
- package/es/components/app-layout/AppLayout.vue.mjs +2 -2
- package/es/components/app-layout/AppLayout.vue2.mjs +95 -93
- package/es/components/app-layout/AppSidebar.vue.mjs +2 -2
- package/es/components/app-layout/AppSidebar.vue2.mjs +79 -82
- package/es/components/app-layout/AppTheme.vue.mjs +7 -0
- package/es/components/app-layout/AppTheme.vue2.mjs +38 -0
- package/es/components/data-view/DataListView.vue.mjs +2 -2
- package/es/components/data-view/DataListView.vue2.mjs +36 -36
- package/es/components/display/ActionConfirm.vue2.mjs +16 -16
- package/es/components/display/HeightProvider.vue.mjs +10 -10
- package/es/components/display/TabsHeader.vue.mjs +4 -4
- package/es/components/display/TabsHeader.vue2.mjs +34 -34
- package/es/components/display/TabsMain.vue.mjs +40 -39
- package/es/components/display/TabsRefineFlow.vue.mjs +30 -28
- package/es/components/form/FormItem.vue.mjs +1 -1
- package/es/components/form/FormItem.vue2.mjs +75 -81
- package/es/components/form/FormItemNestForm.vue.mjs +7 -0
- package/es/components/form/FormItemNestForm.vue2.mjs +49 -0
- package/es/components/form/FormItemNestFormList.vue.mjs +7 -0
- package/es/components/form/FormItemNestFormList.vue2.mjs +137 -0
- package/es/components/form/FormMain.vue.mjs +5 -147
- package/es/components/form/FormMain.vue2.mjs +160 -2
- package/es/components/form/FormRadioGroup.vue.mjs +42 -49
- package/es/components/form/FormSearch.vue.mjs +2 -2
- package/es/components/form/FormSearch.vue2.mjs +122 -128
- package/es/components/form/FormSelect.vue.mjs +34 -40
- package/es/components/form/FormSubmitBtn.vue.mjs +23 -28
- package/es/components/form/FormSubmitPanel.vue.mjs +2 -2
- package/es/components/form/FormSubmitPanel.vue2.mjs +29 -28
- package/es/components/form/FormTree.vue.mjs +16 -21
- package/es/components/form/FormVerifyCode.vue.mjs +37 -43
- package/es/components/form/FormVerifyImage.vue.mjs +2 -2
- package/es/components/form/FormVerifyImage.vue2.mjs +36 -41
- package/es/components/form/nest-form-item-list.mjs +71 -0
- package/es/components/form/nest-form-item.mjs +42 -0
- package/es/components/form/nest-registry.mjs +7 -0
- package/es/components/form/use-nest-form-list.mjs +22 -0
- package/es/components/form/use-nest-form.mjs +34 -0
- package/es/components/form/use-nest-layout-scale.mjs +14 -0
- package/es/components/form/utils.mjs +77 -61
- package/es/components/list-page/ListPage.vue.mjs +2 -2
- package/es/components/list-page/ListPage.vue2.mjs +134 -139
- package/es/components/menu/MenuItemSub.vue.mjs +41 -48
- package/es/components/menu/MenuTree.vue.mjs +58 -65
- package/es/components/misc/AutoRefresh.vue.mjs +2 -2
- package/es/components/misc/AutoRefresh.vue2.mjs +44 -51
- package/es/components/misc/AutoRefreshGroup.vue.mjs +2 -2
- package/es/components/misc/AutoRefreshGroup.vue2.mjs +37 -43
- package/es/components/modal/ConfirmModal.vue.mjs +3 -4
- package/es/components/modal/ConfirmModal.vue2.mjs +83 -111
- package/es/components/modal/DetailModal.vue.mjs +38 -41
- package/es/components/panel/PanelEditSwitch.vue.mjs +1 -1
- package/es/components/panel/PanelEditSwitch.vue2.mjs +50 -55
- package/es/components/panel/PanelItemNestForm.vue.mjs +7 -0
- package/es/components/panel/PanelItemNestForm.vue2.mjs +69 -0
- package/es/components/panel/PanelItemNestPanel.vue.mjs +34 -0
- package/es/components/panel/PanelItemNestPanel.vue2.mjs +4 -0
- package/es/components/panel/PanelMain.vue.mjs +1 -1
- package/es/components/panel/PanelMain.vue2.mjs +72 -72
- package/es/components/panel/nest-panel-form.mjs +53 -0
- package/es/components/panel/nest-panel-item.mjs +25 -0
- package/es/components/table/TableMain.vue.mjs +2 -2
- package/es/components/table/TableMain.vue2.mjs +221 -229
- package/es/components/table/TableToolbar.vue.mjs +2 -2
- package/es/components/table/TableToolbar.vue2.mjs +115 -126
- package/es/hooks/use-admin-theme-apply.mjs +84 -0
- package/es/hooks/use-admin-viewport-apply.mjs +27 -0
- package/es/index.mjs +190 -153
- package/es/inject/key.mjs +15 -6
- package/es/store/app.mjs +75 -84
- package/es/style.css +1 -1
- package/es/utils/theme-scale.mjs +37 -0
- package/package.json +2 -4
- package/types/bridge/config-hook.d.ts +91 -0
- package/types/bridge/index.d.ts +108 -8
- package/types/bridge/plugin.d.ts +39 -0
- package/types/bridge/theme.d.ts +85 -0
- package/types/components/app-layout/AppTheme.vue.d.ts +2 -0
- package/types/components/app-layout/types.d.ts +1 -1
- package/types/components/form/FormItem.vue.d.ts +12 -12
- package/types/components/form/FormItemNestForm.vue.d.ts +36 -0
- package/types/components/form/FormItemNestFormList.vue.d.ts +63 -0
- package/types/components/form/FormMain.vue.d.ts +2 -2
- package/types/components/form/FormSearch.vue.d.ts +2 -2
- package/types/components/form/FormTree.vue.d.ts +50 -50
- package/types/components/form/index.d.ts +9 -1
- package/types/components/form/nest-form-item-list.d.ts +63 -0
- package/types/components/form/nest-form-item.d.ts +36 -0
- package/types/components/form/nest-registry.d.ts +22 -0
- package/types/components/form/types.d.ts +2 -0
- package/types/components/form/use-nest-form-list.d.ts +20 -0
- package/types/components/form/use-nest-form.d.ts +26 -0
- package/types/components/form/use-nest-layout-scale.d.ts +17 -0
- package/types/components/form/utils.d.ts +26 -1
- package/types/components/menu/MenuTree.vue.d.ts +10 -10
- package/types/components/modal/ModalShelf.vue.d.ts +1 -1
- package/types/components/panel/PanelItemNestForm.vue.d.ts +35 -0
- package/types/components/panel/PanelItemNestPanel.vue.d.ts +22 -0
- package/types/components/panel/index.d.ts +5 -1
- package/types/components/panel/nest-panel-form.d.ts +38 -0
- package/types/components/panel/nest-panel-item.d.ts +28 -0
- package/types/components/panel/types.d.ts +2 -0
- package/types/components/table/TableMain.vue.d.ts +3 -3
- package/types/hooks/activated.d.ts +2 -2
- package/types/hooks/feel-size.d.ts +1 -1
- package/types/hooks/index.d.ts +2 -0
- package/types/hooks/menus-dispatch.d.ts +5 -5
- package/types/hooks/use-admin-theme-apply.d.ts +17 -0
- package/types/hooks/use-admin-viewport-apply.d.ts +15 -0
- package/types/hooks/use-breakpoint.d.ts +1 -1
- package/types/inject/key.d.ts +46 -1
- package/types/store/app.d.ts +138 -59
- package/types/utils/index.d.ts +1 -0
- package/types/utils/theme-scale.d.ts +35 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# 配置化嵌套范式(FormMain 套 FormMain / PanelMain 套 PanelMain / 交叉互套)— 实现纪要
|
|
2
|
+
|
|
3
|
+
> **定位**:**P1/P2/P3 已实现纪要**。本文原为设计提案(design-only),其后 nest 联结组件落地,P1(校验穿透)、P2(Panel 嵌套)、P3(布局 rebase span 值轴)均已实现,**实现走了比初版设想更干净的路**;仅 P3 的**断点选择轴**(容器查询)留后续 opt-in。
|
|
4
|
+
> **实现去向**:4 个联结薄壳(C1 `FormItemNestForm` / C4 `FormItemNestFormList` / C2 `PanelItemNestPanel` / C3 `PanelItemNestForm`)+ 配套 helper(`nestFormItem` / `nestFormItemList` / `nestPanelItem` / `nestPanelForm`)。
|
|
5
|
+
> **上位原则**:KB `paradigm.md` §3.0.1「非顶级子空间挂载薄壳(递归下探二等公民层)」——本文是该范式在 Form/Panel 自嵌套 + 交叉嵌套切片上的工程纪要。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. 范式:薄壳即嵌套(已落地)
|
|
10
|
+
|
|
11
|
+
FormMain / PanelMain **本身没有**「表单套表单 / 面板套面板」的一等 prop 支持,但**也不需要**——两族配置化 item 的渲染出口(`render` / `editorRender`)本就是**开放契约**:返回 `VNode[]` 即可,内容由配置方决定。
|
|
12
|
+
|
|
13
|
+
> 嵌套 = 在一个 item 的 `render`/`editorRender` 里套一层**薄壳**(联结组件),薄壳内部挂一个**新的配置化容器**(子 FormMain / PanelMain)。只要薄壳对外仍满足父容器对该 item 的契约(值、校验、布局),父容器无感知,嵌套即成立。
|
|
14
|
+
|
|
15
|
+
三种形态(无界组合,均已落地):
|
|
16
|
+
- **Form 套 Form**:C1 `FormItemNestForm`(1:1)/ C4 `FormItemNestFormList`(1:N 数组)。
|
|
17
|
+
- **Panel 套 Panel**:C2 `PanelItemNestPanel`(纯展示)。
|
|
18
|
+
- **交叉互套**:C3 `PanelItemNestForm`(Panel 项编辑态内嵌 FormMain)。
|
|
19
|
+
|
|
20
|
+
> KB 视角的本体定位:联结薄壳 = 把**空间二等公民**(子 FormMain/PanelMain,当不了空间根)适配成满足父 item 契约的可嵌挂载件,**非空间一等公民**。见 `paradigm.md` §3.0.1。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. P1 校验穿透 — ✅ 已实现(registry 级联,非初版 validator 桥)
|
|
25
|
+
|
|
26
|
+
### 实际落地
|
|
27
|
+
|
|
28
|
+
- **form 族经 registry 级联**:`FormItemNestForm`(C1)/ `FormItemNestFormList`(C4)经 `useNestForm` / `useNestFormList` 把子 `FormMain` 的 `{ validate, clearValidate, resetFields }` 注册进**最近祖先 FormMain** 的 `exposeMap`(`NestFormExposeMap = shallowReactive<Record<itemKey, NestFormExpose>>`,`nest-registry.ts`)。父顶层一次 `validate/clearValidate/resetFields` 即经 `exposeMap` 级联到子(C4 为聚合 expose + fan-out 遍历 N 行)。
|
|
29
|
+
- **对齐 hideKeyList**:父 FormMain `validate` 按 item key 过滤——整 list 被 hide 时不级联(ADR-8)。
|
|
30
|
+
- **panel 族不接 registry**:panel 是 per-item submit、无父顶层 validate,故 C3 `PanelItemNestForm` 改走组件内**局部 `validateChild`**(提交前自校验,reject 留编辑态);C2 纯展示无校验。
|
|
31
|
+
|
|
32
|
+
> **与初版提案的差异(求真)**:提案曾设想用 item `rules` 的 async `validator` 作「校验穿透桥」。**实现未采用**——registry/exposeMap 级联更干净(无需把子 formInstance 塞进规则闭包,天然对齐 hideKeyList)。初版 validator 桥设想已废弃,不再保留为方向。
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. P2 PanelMain 嵌套 — ✅ 已实现
|
|
37
|
+
|
|
38
|
+
- **展示态**(C2 `PanelItemNestPanel`):内层 PanelMain 置 `itemCard=false` → 子项平铺("一项展示多字段"观感,本质潜套 PanelMain);值贯通 = `render` 的 `scope.value` 嵌套对象只读直供子 PanelMain。
|
|
39
|
+
- **编辑态**(C3 `PanelItemNestForm`):经 `editorRender`(优先级高于 `editorConfig`,互斥)挂子 FormMain;`PanelEditSwitch` 进编辑深克隆**草稿**,子 FormMain 绑草稿 in-place,校验通过 `submitFn(草稿) → closeEdit` **回流**真实 data,取消弃草稿。这正是「配置式 `editorConfig` 单字段表达不了的多字段子表单」的合规 escape hatch。
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 4. P3 嵌套后的布局继承(layout 基于父 item 实际宽而非屏幕)— ✅ 已实现(span 值轴;断点选择轴留 opt-in)
|
|
44
|
+
|
|
45
|
+
### 落地(2026-06-13)
|
|
46
|
+
|
|
47
|
+
- 4 联结薄壳现经 `layoutScale` 累乘因子向子 FormMain/PanelMain 传 rebase 因子:`childScale = parentScale × (24 / 父item span)`,子 `resolveFormLayout(span, scale)` 把 span×scale 后 `ceilToTier` 到档集 `{6,8,12,24}`(封顶 24)。**默认开**;helper 加 `rebase?: boolean`(缺省 `true`,`false` = 逆向逃生口原样直透)。
|
|
48
|
+
- 链路:`FormMain`/`PanelMain` 加 prop `layoutScale`(缺省 1)+ provide `NEST_LAYOUT_SCALE_KEY`;薄壳 `useNestLayoutScale` inject 父 scale 叠本层因子;helper 经 `resolveLayoutSpan(layout)` 把父 item 代表 span 传薄壳。
|
|
49
|
+
- 不变量:叶子字段绝对宽 ≈ `(authoredSpan/24) × 屏宽`,与嵌套深度无关。
|
|
50
|
+
- 设计 + worked examples 见 `docs/specs/2026-06-13-045727-moderate-嵌套布局rebase-P3/design.md`。
|
|
51
|
+
|
|
52
|
+
### 解决的缺口
|
|
53
|
+
|
|
54
|
+
外层 item 用窄栅格(如父 `span:12` = 半宽容器)时,子字段 `span` 相对**容器**算百分比 → 嵌套层过挤;rebase 按父 item 实际分配宽放大子 span,维持字段绝对宽与顶级一致。
|
|
55
|
+
|
|
56
|
+
### 已知近似(v1 接受)
|
|
57
|
+
|
|
58
|
+
- 仅修 **span 值轴**;**断点选择轴**(el 的 `xs/sm/md/lg/xl` 由 **window 宽** media query 选档,非容器宽)留后续 opt-in 容器查询治理。
|
|
59
|
+
- 3+ 层且中间层被 ceil/clamp 时,因子用 authored span 略欠精;2 层常见场景精确。
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 5. 状态小结
|
|
64
|
+
|
|
65
|
+
| # | 缺口 | 状态 | 实际落地 / 遗留 |
|
|
66
|
+
|---|---|---|---|
|
|
67
|
+
| P1 | 校验穿透 | ✅ 已实现 | form 族 registry/exposeMap 级联(C1/C4,ADR-1/8);panel 族局部 validateChild(C3)/ 无校验(C2)。初版 validator 桥设想已废 |
|
|
68
|
+
| P2 | Panel 嵌套 | ✅ 已实现 | C2 展示(itemCard 平铺)+ C3 编辑(editorRender 挂子 FormMain + 草稿回流) |
|
|
69
|
+
| P3 | 布局继承 rebase | ✅ 已实现(span 值轴) | layoutScale 累乘链 + ceilToTier 档集;断点选择轴留 opt-in 容器查询 |
|
|
70
|
+
|
|
71
|
+
**遗留边界**:本文不再据 P1/P2/P3 实现展开(已落地,API 见 KB 组件档 + MIGRATION §38);唯一未做项为 P3 的**断点选择轴**(容器查询替代 viewport 媒体断点),留后续 opt-in spec。
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 附:相关源码 / KB 锚点
|
|
76
|
+
|
|
77
|
+
- 联结薄壳源:`packages/core/src/components/form/{FormItemNestForm,FormItemNestFormList}.vue` + `{nest-form-item,nest-form-item-list}.ts`;`packages/core/src/components/panel/{PanelItemNestPanel,PanelItemNestForm}.vue` + `{nest-panel-item,nest-panel-form}.ts`
|
|
78
|
+
- registry 基建:`packages/core/src/components/form/{nest-registry,use-nest-form,use-nest-form-list}.ts`
|
|
79
|
+
- 上位范式 + 组件 API(KB):`~/.claude/knowledge/admin-core/paradigm.md` §3.0.1;`components/{FormItemNestForm,FormItemNestFormList,PanelItemNestPanel,PanelItemNestForm}.md`
|
|
80
|
+
- 嵌套三件套实现 spec(含 ADR-1/5/6/8):`docs/specs/2026-06-12-020608-complex-配置化嵌套联结组件Nest三件套/`
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { reactive as e, readonly as r } from "vue";
|
|
2
|
+
function s(o) {
|
|
3
|
+
const c = e(o.APP_BASE_INFO), _ = e(o.APP_LAYOUT_HEADER_CONFIG), A = e(o.APP_LAYOUT_FOOTER_CONFIG), O = e(o.APP_LAYOUT_SIDEBAR_CONFIG), P = e(o.APP_LAYOUT_BREADCRUMB_CONFIG), t = e(o.APP_LAYOUT_BODY_CONFIG), a = e(o.APP_LAYOUT_VIEWPORT_CONFIG), I = e(o.APP_THEME_CONFIG), F = {
|
|
4
|
+
APP_BASE_INFO: c,
|
|
5
|
+
APP_LAYOUT_HEADER_CONFIG: _,
|
|
6
|
+
APP_LAYOUT_FOOTER_CONFIG: A,
|
|
7
|
+
APP_LAYOUT_SIDEBAR_CONFIG: O,
|
|
8
|
+
APP_LAYOUT_BREADCRUMB_CONFIG: P,
|
|
9
|
+
APP_LAYOUT_BODY_CONFIG: t,
|
|
10
|
+
APP_LAYOUT_VIEWPORT_CONFIG: a,
|
|
11
|
+
APP_THEME_CONFIG: I
|
|
12
|
+
}, T = e({
|
|
13
|
+
header: _,
|
|
14
|
+
footer: A,
|
|
15
|
+
sidebar: O,
|
|
16
|
+
breadcrumb: P,
|
|
17
|
+
body: t,
|
|
18
|
+
viewport: a
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
update: (E, B) => {
|
|
22
|
+
Object.assign(F[E], B);
|
|
23
|
+
},
|
|
24
|
+
roBaseInfo: r(c),
|
|
25
|
+
roHeader: r(_),
|
|
26
|
+
roFooter: r(A),
|
|
27
|
+
roSidebar: r(O),
|
|
28
|
+
roBreadcrumb: r(P),
|
|
29
|
+
roBody: r(t),
|
|
30
|
+
roViewport: r(a),
|
|
31
|
+
roTheme: r(I),
|
|
32
|
+
roLayout: r(T)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
s as createBridgeConfigHook
|
|
37
|
+
};
|
package/es/bridge/index.mjs
CHANGED
|
@@ -1,104 +1,199 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { computed as h } from "vue";
|
|
2
|
+
import { createStorageWithNamespace as G } from "./storage.mjs";
|
|
3
|
+
import { createUseState as d } from "./state.mjs";
|
|
4
|
+
import { createGenerateRouteMetaRawTree as l } from "./route.mjs";
|
|
5
|
+
import { createBridgeConfigHook as L } from "./config-hook.mjs";
|
|
6
|
+
import { createBridgePluginHost as B } from "./plugin.mjs";
|
|
7
|
+
import { createBridgeThemeHook as k } from "./theme.mjs";
|
|
8
|
+
import { ADMIN_BRIDGE_KEY as Y } from "../inject/key.mjs";
|
|
9
|
+
function V(r) {
|
|
10
|
+
const F = r.APP_CACHE_CONFIG.namespace;
|
|
6
11
|
let _;
|
|
7
12
|
F === "" ? (console.error(
|
|
8
13
|
"[adminBridge] APP_CACHE_CONFIG.namespace 为空,已兜底为 'ADMIN_CORE'"
|
|
9
|
-
), _ = "ADMIN_CORE") : _ = F, Object.freeze(
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
),
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
), _ = "ADMIN_CORE") : _ = F, Object.freeze(r);
|
|
15
|
+
const a = G(_), u = r.routes, C = r.getUserInfoInitFn, N = r.userInfoAccess, m = d(_), s = l(
|
|
16
|
+
r.APP_ROUTER_META_DEFAULT_CONFIG
|
|
17
|
+
), t = L({
|
|
18
|
+
APP_BASE_INFO: r.APP_BASE_INFO,
|
|
19
|
+
APP_THEME_CONFIG: r.APP_THEME_CONFIG,
|
|
20
|
+
APP_LAYOUT_HEADER_CONFIG: r.APP_LAYOUT_HEADER_CONFIG,
|
|
21
|
+
APP_LAYOUT_FOOTER_CONFIG: r.APP_LAYOUT_FOOTER_CONFIG,
|
|
22
|
+
APP_LAYOUT_SIDEBAR_CONFIG: r.APP_LAYOUT_SIDEBAR_CONFIG,
|
|
23
|
+
APP_LAYOUT_BREADCRUMB_CONFIG: r.APP_LAYOUT_BREADCRUMB_CONFIG,
|
|
24
|
+
APP_LAYOUT_BODY_CONFIG: r.APP_LAYOUT_BODY_CONFIG,
|
|
25
|
+
// viewport 边框:app 可整体不传 / 传部分字段,与核内默认四边 0 浅合并补全
|
|
26
|
+
// (config-hook reactive 入参 [MUST] 全字段非 undefined,故此处合并而非透传)。
|
|
27
|
+
APP_LAYOUT_VIEWPORT_CONFIG: {
|
|
28
|
+
paddingTop: 0,
|
|
29
|
+
paddingRight: 0,
|
|
30
|
+
paddingBottom: 0,
|
|
31
|
+
paddingLeft: 0,
|
|
32
|
+
...r.APP_LAYOUT_VIEWPORT_CONFIG
|
|
33
|
+
}
|
|
34
|
+
}), P = k({
|
|
35
|
+
initConfig: r.APP_THEME_CONFIG,
|
|
36
|
+
update: t.update,
|
|
37
|
+
storage: a
|
|
38
|
+
}), c = h(
|
|
39
|
+
() => P.themeIsDark.value ? t.roTheme.dark : t.roTheme.light
|
|
40
|
+
);
|
|
41
|
+
let n, o, O, T, I, i, E, f;
|
|
42
|
+
const A = (e) => `admin bridge: ${e} 未注册`, R = B(), g = {
|
|
43
|
+
register(e) {
|
|
44
|
+
e.getToken && (n = e.getToken), e.goToLogin && (o = e.goToLogin), e.refreshToken && (O = e.refreshToken), e.refreshAuth && (T = e.refreshAuth), e.loginApi && (I = e.loginApi), e.logoutApi && (i = e.logoutApi), e.getUserInfoApi && (E = e.getUserInfoApi), e.refreshTokenApi && (f = e.refreshTokenApi);
|
|
24
45
|
},
|
|
25
46
|
// 已注册返回 undefined 是合法业务态不 throw
|
|
26
47
|
// v3 终锁 Δ8b:零参 facade(BR-1 ③ 终裁——core 对 UserInfo 不透明 + 拦截器无 info 源)
|
|
27
48
|
getToken() {
|
|
28
|
-
if (!
|
|
29
|
-
return
|
|
49
|
+
if (!n) throw new Error(A("getToken"));
|
|
50
|
+
return n();
|
|
30
51
|
},
|
|
31
52
|
goToLogin() {
|
|
32
|
-
if (!
|
|
33
|
-
|
|
53
|
+
if (!o) throw new Error(A("goToLogin"));
|
|
54
|
+
o();
|
|
34
55
|
},
|
|
35
56
|
// 异步对:未注册才返回 rejected Promise(既有降级语义保留)。
|
|
36
57
|
refreshToken() {
|
|
37
|
-
return
|
|
58
|
+
return O ? O().then(() => {
|
|
38
59
|
}) : Promise.reject(new Error(A("refreshToken")));
|
|
39
60
|
},
|
|
40
61
|
refreshAuth() {
|
|
41
|
-
return
|
|
62
|
+
return T ? T().then(() => {
|
|
42
63
|
}) : Promise.reject(new Error(A("refreshAuth")));
|
|
43
64
|
},
|
|
44
65
|
getStorage() {
|
|
45
|
-
return
|
|
66
|
+
return a;
|
|
46
67
|
},
|
|
47
68
|
getRoutes() {
|
|
48
|
-
return
|
|
69
|
+
return u;
|
|
49
70
|
},
|
|
50
71
|
getUserInfoInitFn() {
|
|
51
|
-
return
|
|
72
|
+
return C;
|
|
52
73
|
},
|
|
53
|
-
useState:
|
|
54
|
-
generateRouteMetaRawTree:
|
|
74
|
+
useState: m,
|
|
75
|
+
generateRouteMetaRawTree: s,
|
|
55
76
|
// ============ #2.5 期 12 readonly 属性值挂载(per ADR-1 sibling pattern 复用 useState / generateRouteMetaRawTree) ============
|
|
56
|
-
|
|
57
|
-
|
|
77
|
+
// 插件系统一期:本期 7 字段(BASE_INFO / 5 布局子 / THEME)+ APP_LAYOUT_CONFIG
|
|
78
|
+
// 改挂 configHook 的 readonly(reactive()) 响应式只读视图——经 bridge.update 跟随。
|
|
79
|
+
/**
|
|
80
|
+
* 应用基础信息(**响应式只读视图**,插件系统一期改)。
|
|
81
|
+
*
|
|
82
|
+
* 现为 vue `readonly(reactive(...))` 包裹——经 `bridge.update("APP_BASE_INFO", partial)`
|
|
83
|
+
* 更新后本属性自动跟随。[SHOULD] 在 `computed` / 响应式上下文中读取,[MUST NOT]
|
|
84
|
+
* 解构或一次性快照取值(`const x = bridge.APP_BASE_INFO.foo` ⚠️ 快照定格,update 后不变)。
|
|
85
|
+
*/
|
|
86
|
+
APP_BASE_INFO: t.roBaseInfo,
|
|
58
87
|
/** 应用环境信息(per #2.5 期 REQ-1) */
|
|
59
|
-
APP_ENV_INFO:
|
|
88
|
+
APP_ENV_INFO: r.APP_ENV_INFO,
|
|
60
89
|
/** 应用缓存配置(per #2.5 期 REQ-1) */
|
|
61
|
-
APP_CACHE_CONFIG:
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
90
|
+
APP_CACHE_CONFIG: r.APP_CACHE_CONFIG,
|
|
91
|
+
/**
|
|
92
|
+
* 应用布局-header 配置(**响应式只读视图**,插件系统一期改)。
|
|
93
|
+
*
|
|
94
|
+
* `readonly(reactive(...))` 包裹——`bridge.update("APP_LAYOUT_HEADER_CONFIG", partial)`
|
|
95
|
+
* 后自动跟随。[SHOULD] 响应式上下文 / `computed` 读取,[MUST NOT] 解构/快照(⚠️ 定格)。
|
|
96
|
+
*/
|
|
97
|
+
APP_LAYOUT_HEADER_CONFIG: t.roHeader,
|
|
98
|
+
/**
|
|
99
|
+
* 应用布局-footer 配置(**响应式只读视图**,插件系统一期改)。
|
|
100
|
+
*
|
|
101
|
+
* `readonly(reactive(...))`——`bridge.update("APP_LAYOUT_FOOTER_CONFIG", partial)`
|
|
102
|
+
* 后跟随。[SHOULD] 响应式上下文读取,[MUST NOT] 解构/快照(⚠️ 定格)。
|
|
103
|
+
*/
|
|
104
|
+
APP_LAYOUT_FOOTER_CONFIG: t.roFooter,
|
|
105
|
+
/**
|
|
106
|
+
* 应用布局-sidebar 配置(**响应式只读视图**,插件系统一期改)。
|
|
107
|
+
*
|
|
108
|
+
* `readonly(reactive(...))`——`bridge.update("APP_LAYOUT_SIDEBAR_CONFIG", partial)`
|
|
109
|
+
* 后跟随(一级浅合并,传 `{width}` 保留 `collapseWidth`)。[SHOULD] 响应式上下文
|
|
110
|
+
* 读取,[MUST NOT] 解构/快照(⚠️ 定格)。
|
|
111
|
+
*/
|
|
112
|
+
APP_LAYOUT_SIDEBAR_CONFIG: t.roSidebar,
|
|
113
|
+
/**
|
|
114
|
+
* 应用布局-面包屑配置(**响应式只读视图**,插件系统一期改)。
|
|
115
|
+
*
|
|
116
|
+
* `readonly(reactive(...))`——`bridge.update("APP_LAYOUT_BREADCRUMB_CONFIG", partial)`
|
|
117
|
+
* 后跟随。[SHOULD] 响应式上下文读取,[MUST NOT] 解构/快照(⚠️ 定格)。
|
|
118
|
+
*/
|
|
119
|
+
APP_LAYOUT_BREADCRUMB_CONFIG: t.roBreadcrumb,
|
|
120
|
+
/**
|
|
121
|
+
* 应用布局-页面主体配置(**响应式只读视图**,插件系统一期改)。
|
|
122
|
+
*
|
|
123
|
+
* `readonly(reactive(...))`——`bridge.update("APP_LAYOUT_BODY_CONFIG", partial)`
|
|
124
|
+
* 后跟随。[SHOULD] 响应式上下文读取,[MUST NOT] 解构/快照(⚠️ 定格)。
|
|
125
|
+
*/
|
|
126
|
+
APP_LAYOUT_BODY_CONFIG: t.roBody,
|
|
127
|
+
/**
|
|
128
|
+
* 应用布局-视口边框配置(**响应式只读视图**)。
|
|
129
|
+
*
|
|
130
|
+
* `readonly(reactive(...))`——`bridge.update("APP_LAYOUT_VIEWPORT_CONFIG", partial)`
|
|
131
|
+
* 后跟随(一级浅合并,传 `{paddingTop}` 保留其余三边)。store/app 经此派生 viewport
|
|
132
|
+
* padding 给 Header/Sidebar fixed 锚点 + AppBody calc。[MUST NOT] 解构/快照(⚠️ 定格)。
|
|
133
|
+
*/
|
|
134
|
+
APP_LAYOUT_VIEWPORT_CONFIG: t.roViewport,
|
|
135
|
+
/**
|
|
136
|
+
* 应用布局聚合配置(**响应式只读视图**,插件系统一期改)。
|
|
137
|
+
*
|
|
138
|
+
* 聚合 5 子布局配置的响应式只读视图;5 子任一 `update` 后本聚合的对应子字段跟随。
|
|
139
|
+
* `readonly(reactive({header, footer, sidebar, breadcrumb, body}))`——不再是
|
|
140
|
+
* `Object.freeze` 静态聚合。[SHOULD] 响应式上下文读取,[MUST NOT] 解构/快照(⚠️ 定格)。
|
|
141
|
+
*/
|
|
142
|
+
APP_LAYOUT_CONFIG: t.roLayout,
|
|
74
143
|
/** 应用路由元信息默认配置(per #2.5 期 REQ-1) */
|
|
75
|
-
APP_ROUTER_META_DEFAULT_CONFIG:
|
|
144
|
+
APP_ROUTER_META_DEFAULT_CONFIG: r.APP_ROUTER_META_DEFAULT_CONFIG,
|
|
76
145
|
/** 应用路由配置(per #2.5 期 REQ-1) */
|
|
77
|
-
APP_ROUTER_CONFIG:
|
|
146
|
+
APP_ROUTER_CONFIG: r.APP_ROUTER_CONFIG,
|
|
78
147
|
/** 应用路由路径配置(per #7.3 期 readonly 挂载) */
|
|
79
|
-
APP_ROUTER_PATHS_CONFIG:
|
|
80
|
-
/**
|
|
81
|
-
|
|
148
|
+
APP_ROUTER_PATHS_CONFIG: r.APP_ROUTER_PATHS_CONFIG,
|
|
149
|
+
/**
|
|
150
|
+
* 应用主题配置(**响应式只读视图**,插件系统一期改)。
|
|
151
|
+
*
|
|
152
|
+
* `readonly(reactive(...))`——`bridge.update("APP_THEME_CONFIG", {light: newLight})`
|
|
153
|
+
* 一级浅合并整体替换 `light`、保留 `dark`,后自动跟随。[SHOULD] 响应式上下文读取,
|
|
154
|
+
* [MUST NOT] 解构/快照(⚠️ 定格)。
|
|
155
|
+
*/
|
|
156
|
+
APP_THEME_CONFIG: t.roTheme,
|
|
157
|
+
/** 主题模块(架构反转:风格切换真相源在 bridge;插件经 theme.add 注册风格) */
|
|
158
|
+
theme: P.theme,
|
|
159
|
+
/** 当前风格名(响应式只读真相源) */
|
|
160
|
+
themeStyle: P.themeStyle,
|
|
161
|
+
/** 是否暗色(响应式只读真相源;appStore / 挂值 composable 读此) */
|
|
162
|
+
themeIsDark: P.themeIsDark,
|
|
163
|
+
/** 当前生效 JS 主题色(输出 B;MenuTree/布局直读、appStore.theme 转发) */
|
|
164
|
+
themeColors: c,
|
|
82
165
|
/** 用户信息字段访问器集(第一宪法:业务注入 get/set 读写 token/refreshToken/permission) */
|
|
83
166
|
userInfoAccess: N,
|
|
167
|
+
// 插件系统一期:update(REQ-1)+ install(REQ-9)挂载。
|
|
168
|
+
// install 箭头函数闭包引用 bridgeInstance([MUST NOT] 用 this——strict
|
|
169
|
+
// noImplicitThis);provide 整 bridge 自身;零单例([MUST NOT] globalThis/模块级缓存)。
|
|
170
|
+
update: t.update,
|
|
171
|
+
use: (e, U) => R.use({
|
|
172
|
+
bridge: g,
|
|
173
|
+
update: t.update,
|
|
174
|
+
plugin: e,
|
|
175
|
+
options: U
|
|
176
|
+
}),
|
|
177
|
+
install: (e) => (e.provide(Y, g), e),
|
|
84
178
|
// 异步对:未注册返回 rejected 原生 Error(#4a-2 per-method 降级)
|
|
85
|
-
loginApi(
|
|
86
|
-
return
|
|
179
|
+
loginApi(e) {
|
|
180
|
+
return I ? I(e) : Promise.reject(new Error(A("loginApi")));
|
|
87
181
|
},
|
|
88
182
|
logoutApi() {
|
|
89
|
-
return
|
|
183
|
+
return i ? i() : Promise.reject(new Error(A("logoutApi")));
|
|
90
184
|
},
|
|
91
185
|
getUserInfoApi() {
|
|
92
|
-
return
|
|
186
|
+
return E ? E() : Promise.reject(new Error(A("getUserInfoApi")));
|
|
93
187
|
},
|
|
94
|
-
refreshTokenApi(
|
|
95
|
-
return
|
|
188
|
+
refreshTokenApi(e) {
|
|
189
|
+
return f ? f(e) : Promise.reject(new Error(A("refreshTokenApi")));
|
|
96
190
|
}
|
|
97
191
|
};
|
|
192
|
+
return g;
|
|
98
193
|
}
|
|
99
194
|
export {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
195
|
+
V as createAdminBridge,
|
|
196
|
+
l as createGenerateRouteMetaRawTree,
|
|
197
|
+
G as createStorageWithNamespace,
|
|
198
|
+
d as createUseState
|
|
104
199
|
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import f from "lodash/omit";
|
|
2
|
+
function d() {
|
|
3
|
+
const i = /* @__PURE__ */ new WeakSet(), o = /* @__PURE__ */ new Set();
|
|
4
|
+
return { use: (u) => {
|
|
5
|
+
const { bridge: t, update: l, plugin: n, options: g } = u, s = n, r = typeof n == "function" ? n : n.install, e = typeof n == "function" ? void 0 : n.name;
|
|
6
|
+
if (typeof r != "function")
|
|
7
|
+
throw new Error("admin bridge plugin: install must be a function");
|
|
8
|
+
if (i.has(s) || e && o.has(e))
|
|
9
|
+
return t;
|
|
10
|
+
const a = f(t, [
|
|
11
|
+
"init",
|
|
12
|
+
"register",
|
|
13
|
+
"getToken",
|
|
14
|
+
"goToLogin",
|
|
15
|
+
"refreshToken",
|
|
16
|
+
"refreshAuth",
|
|
17
|
+
"loginApi",
|
|
18
|
+
"logoutApi",
|
|
19
|
+
"getUserInfoApi",
|
|
20
|
+
"refreshTokenApi",
|
|
21
|
+
"use",
|
|
22
|
+
"install"
|
|
23
|
+
]);
|
|
24
|
+
return r({ bridge: a, update: l }, g), i.add(s), e && o.add(e), t;
|
|
25
|
+
} };
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
d as createBridgePluginHost
|
|
29
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ref as f, readonly as d } from "vue";
|
|
2
|
+
const o = "default", E = "默认", b = "admin-core-theme", I = (t) => ({
|
|
3
|
+
light: { ...t.light },
|
|
4
|
+
dark: { ...t.dark }
|
|
5
|
+
}), A = (t, c) => {
|
|
6
|
+
const r = t.getItem(c);
|
|
7
|
+
if (!r) return null;
|
|
8
|
+
try {
|
|
9
|
+
const s = JSON.parse(r);
|
|
10
|
+
return s && typeof s == "object" ? s : null;
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
function _(t) {
|
|
16
|
+
const c = t.storageKey ?? b, r = /* @__PURE__ */ new Map(), s = f(o), u = f(!1), g = f([]), n = f({});
|
|
17
|
+
let i = o;
|
|
18
|
+
const a = A(t.storage, c);
|
|
19
|
+
a && (typeof a.themeStyle == "string" && a.themeStyle && (i = a.themeStyle), typeof a.themeIsDark == "boolean" && (u.value = a.themeIsDark));
|
|
20
|
+
const h = () => {
|
|
21
|
+
t.storage.setItem(
|
|
22
|
+
c,
|
|
23
|
+
JSON.stringify({
|
|
24
|
+
themeStyle: s.value,
|
|
25
|
+
themeIsDark: u.value
|
|
26
|
+
})
|
|
27
|
+
);
|
|
28
|
+
}, v = () => {
|
|
29
|
+
g.value = Array.from(r.keys());
|
|
30
|
+
}, m = (e) => {
|
|
31
|
+
t.update("APP_THEME_CONFIG", { light: e.light, dark: e.dark });
|
|
32
|
+
}, y = (e) => {
|
|
33
|
+
const l = r.get(e);
|
|
34
|
+
if (!l) {
|
|
35
|
+
const k = r.get(o);
|
|
36
|
+
if (!k) return;
|
|
37
|
+
m(k), s.value = o, h();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
m(l), s.value = e, h();
|
|
41
|
+
}, S = (e) => {
|
|
42
|
+
u.value = !!e, h();
|
|
43
|
+
}, p = (e, l) => {
|
|
44
|
+
r.set(e, I(l.config)), n.value = { ...n.value, [e]: l.label ?? e }, v(), e === i && s.value !== i && y(e);
|
|
45
|
+
}, L = (e) => {
|
|
46
|
+
if (e === o || !r.delete(e)) return;
|
|
47
|
+
const l = { ...n.value };
|
|
48
|
+
delete l[e], n.value = l, v(), s.value === e && y(o);
|
|
49
|
+
}, D = (e) => n.value[e] ?? e;
|
|
50
|
+
return p(o, { config: t.initConfig, label: E }), {
|
|
51
|
+
theme: {
|
|
52
|
+
add: p,
|
|
53
|
+
remove: L,
|
|
54
|
+
setStyle: y,
|
|
55
|
+
setDark: S,
|
|
56
|
+
list: d(g),
|
|
57
|
+
labelOf: D
|
|
58
|
+
},
|
|
59
|
+
themeStyle: d(s),
|
|
60
|
+
themeIsDark: d(u)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
_ as createBridgeThemeHook
|
|
65
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import o from "./AppBody.vue2.mjs";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import p from "../../_virtual/_plugin-vue_export-helper.mjs";
|
|
4
|
-
const m = /* @__PURE__ */ p(o, [["__scopeId", "data-v-
|
|
4
|
+
const m = /* @__PURE__ */ p(o, [["__scopeId", "data-v-ae442089"]]);
|
|
5
5
|
export {
|
|
6
6
|
m as default
|
|
7
7
|
};
|
|
@@ -1,87 +1,85 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "element-plus
|
|
3
|
-
import "
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import { useActivatedExec as W, useActivatedEvent as q } from "../../hooks/activated.mjs";
|
|
9
|
-
const re = /* @__PURE__ */ F({
|
|
1
|
+
import { defineComponent as T, useCssVars as V, inject as _, ref as h, computed as t, provide as L, watch as F, resolveComponent as H, openBlock as n, createElementBlock as N, normalizeStyle as A, createElementVNode as I, createBlock as r, unref as E, withCtx as b, createVNode as w, createCommentVNode as a, KeepAlive as k, resolveDynamicComponent as S, renderSlot as U } from "vue";
|
|
2
|
+
import { ElAffix as Y } from "element-plus";
|
|
3
|
+
import G from "./AppBreadcrumb.vue.mjs";
|
|
4
|
+
import $ from "lodash/debounce";
|
|
5
|
+
import { APP_LAYOUT_APP_STORE_KEY as D, APP_LAYOUT_BRIDGE_KEY as z, BODY_CONTENT_VIEWPORT_HEIGHT as K } from "../../inject/key.mjs";
|
|
6
|
+
import { useActivatedExec as M, useActivatedEvent as j } from "../../hooks/activated.mjs";
|
|
7
|
+
const te = /* @__PURE__ */ T({
|
|
10
8
|
__name: "AppBody",
|
|
11
9
|
props: {
|
|
12
10
|
menuFlatList: { default: () => [] }
|
|
13
11
|
},
|
|
14
|
-
setup(
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
setup(P) {
|
|
13
|
+
V((e) => ({
|
|
14
|
+
ae6fc168: s.value
|
|
17
15
|
}));
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
() => `calc(${
|
|
22
|
-
),
|
|
23
|
-
|
|
24
|
-
},
|
|
16
|
+
const o = _(D), l = _(z), g = l.APP_ROUTER_CONFIG, c = h(!1), u = t(() => l.APP_LAYOUT_BREADCRUMB_CONFIG.height), d = h(0);
|
|
17
|
+
L(K, d);
|
|
18
|
+
const x = t(() => o.bodyShimPadding), m = t(() => o.bodyShimStyle), C = t(() => o.bodyStyle), p = t(() => o.showBreadcrumb), O = t(() => parseFloat(`${o.bodyStyle.paddingTop ?? 0}`) || 0), s = t(
|
|
19
|
+
() => `calc(${m.value.minHeight} - ${p.value && c.value ? u.value : 0}px - ${x.value * 2}px)`
|
|
20
|
+
), B = (e) => {
|
|
21
|
+
c.value = e;
|
|
22
|
+
}, i = $(() => {
|
|
25
23
|
const e = document.createElement("div");
|
|
26
|
-
e.style.height =
|
|
24
|
+
e.style.height = s.value, e.style.position = "fixed", e.style.left = "100%", e.style.top = "100%", e.style.opacity = "0", e.style.pointerEvents = "none", document.body.appendChild(e), d.value = e.clientHeight, e.remove();
|
|
27
25
|
}, 16);
|
|
28
|
-
return
|
|
29
|
-
|
|
30
|
-
}),
|
|
26
|
+
return M(() => {
|
|
27
|
+
i();
|
|
28
|
+
}), j(
|
|
31
29
|
() => {
|
|
32
|
-
window.addEventListener("resize",
|
|
30
|
+
window.addEventListener("resize", i);
|
|
33
31
|
},
|
|
34
32
|
() => {
|
|
35
|
-
window.removeEventListener("resize",
|
|
33
|
+
window.removeEventListener("resize", i);
|
|
36
34
|
}
|
|
37
|
-
),
|
|
38
|
-
|
|
39
|
-
}), (e,
|
|
40
|
-
const
|
|
41
|
-
return
|
|
35
|
+
), F(s, () => {
|
|
36
|
+
i();
|
|
37
|
+
}), (e, W) => {
|
|
38
|
+
const R = H("RouterView");
|
|
39
|
+
return n(), N("div", {
|
|
42
40
|
class: "app-body",
|
|
43
|
-
style:
|
|
41
|
+
style: A(C.value)
|
|
44
42
|
}, [
|
|
45
|
-
|
|
43
|
+
I("div", {
|
|
46
44
|
class: "app-body-shim",
|
|
47
|
-
style:
|
|
45
|
+
style: A(m.value)
|
|
48
46
|
}, [
|
|
49
|
-
|
|
47
|
+
p.value ? (n(), r(E(Y), {
|
|
50
48
|
key: 0,
|
|
51
|
-
offset:
|
|
49
|
+
offset: O.value
|
|
52
50
|
}, {
|
|
53
51
|
default: b(() => [
|
|
54
|
-
|
|
55
|
-
height:
|
|
56
|
-
menuFlatList:
|
|
57
|
-
onShow:
|
|
52
|
+
w(G, {
|
|
53
|
+
height: u.value,
|
|
54
|
+
menuFlatList: P.menuFlatList,
|
|
55
|
+
onShow: B
|
|
58
56
|
}, null, 8, ["height", "menuFlatList"])
|
|
59
57
|
]),
|
|
60
58
|
_: 1
|
|
61
59
|
}, 8, ["offset"])) : a("", !0),
|
|
62
|
-
|
|
60
|
+
w(R, null, {
|
|
63
61
|
default: b(({
|
|
64
|
-
Component:
|
|
62
|
+
Component: f,
|
|
65
63
|
route: {
|
|
66
|
-
path:
|
|
67
|
-
meta: { keepAlive:
|
|
64
|
+
path: v,
|
|
65
|
+
meta: { keepAlive: y }
|
|
68
66
|
}
|
|
69
67
|
}) => [
|
|
70
|
-
(
|
|
71
|
-
max:
|
|
68
|
+
(n(), r(k, {
|
|
69
|
+
max: E(g).keepAliveMaxCount
|
|
72
70
|
}, [
|
|
73
|
-
|
|
71
|
+
y ? (n(), r(S(f), { key: v })) : a("", !0)
|
|
74
72
|
], 1032, ["max"])),
|
|
75
|
-
|
|
73
|
+
y ? a("", !0) : (n(), r(S(f), { key: v }))
|
|
76
74
|
]),
|
|
77
75
|
_: 1
|
|
78
76
|
})
|
|
79
77
|
], 4),
|
|
80
|
-
|
|
78
|
+
U(e.$slots, "footer", {}, void 0, !0)
|
|
81
79
|
], 4);
|
|
82
80
|
};
|
|
83
81
|
}
|
|
84
82
|
});
|
|
85
83
|
export {
|
|
86
|
-
|
|
84
|
+
te as default
|
|
87
85
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import o from "./AppBreadcrumb.vue2.mjs";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import r from "../../_virtual/_plugin-vue_export-helper.mjs";
|
|
4
|
-
const a = /* @__PURE__ */ r(o, [["__scopeId", "data-v-
|
|
4
|
+
const a = /* @__PURE__ */ r(o, [["__scopeId", "data-v-9bbe0b05"]]);
|
|
5
5
|
export {
|
|
6
6
|
a as default
|
|
7
7
|
};
|