@robot-admin/layout 3.0.0 → 3.2.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/CHANGELOG.md +164 -144
- package/README.md +519 -410
- package/dist/core/index.cjs +8 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +6 -1
- package/dist/core/index.d.ts +6 -1
- package/dist/core/index.js +7 -1
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +1 -39
- package/dist/index.css +1 -1
- package/dist/index.d.cts +1537 -360
- package/dist/index.d.ts +1537 -360
- package/dist/index.js +3 -2296
- package/dist/naive/index.cjs +1 -0
- package/dist/naive/index.d.cts +2927 -0
- package/dist/naive/index.d.ts +2927 -0
- package/dist/naive/index.js +3 -0
- package/dist/naive-Bd8pxcrF.js +1635 -0
- package/dist/naive-Bd8pxcrF.js.map +1 -0
- package/dist/naive-BfZUS_c8.cjs +28 -0
- package/dist/naive-BfZUS_c8.cjs.map +1 -0
- package/dist/vue/index.cjs +1 -0
- package/dist/vue/index.d.cts +1181 -0
- package/dist/vue/index.d.ts +1181 -0
- package/dist/vue/index.js +2 -0
- package/dist/vue-BRQ1Fg0b.js +739 -0
- package/dist/vue-BRQ1Fg0b.js.map +1 -0
- package/dist/vue-DhbxgFgz.cjs +2 -0
- package/dist/vue-DhbxgFgz.cjs.map +1 -0
- package/package.json +128 -100
- package/src/styles/layouts.scss +137 -82
- package/src/styles/settings.scss +421 -391
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,412 +1,521 @@
|
|
|
1
|
-
# @robot-admin/layout
|
|
2
|
-
|
|
3
|
-
> 布局和设置管理系统 - 为 Robot Admin 提供完整的布局配置管理能力(含 UI 组件)
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@robot-admin/layout)
|
|
6
|
-
[](https://github.com/ChenyCHENYU/robot-admin-packages/blob/main/LICENSE)
|
|
7
|
-
|
|
8
|
-
当前版本:`3.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## ✨ 特性
|
|
13
|
-
|
|
14
|
-
- 🧠 **智能容器模式** - `C_LayoutContainer` 自动分发布局骨架,主项目只需提供业务插槽
|
|
15
|
-
- 🎨 **6 种布局模式** - 左侧 / 顶部 / 混合 / 顶部混合 / 反转混合 / 卡片布局
|
|
16
|
-
- 🎯 **6 套主题预设** - 科技蓝 / 清新绿 / 商务灰 / 活力橙 / 优雅紫 / 经典红
|
|
17
|
-
- 🧩 **开箱即用** - 提供 SettingsDrawer 设置抽屉,覆盖外观 / 布局 / 功能配置
|
|
18
|
-
- 🧭 **菜单展开方式** - 内置传统展开 / 右侧面板两种菜单展开模式配置
|
|
19
|
-
- 🔌 **插槽系统** - 灵活的 slot 机制,主项目仅关注业务组件
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
├──
|
|
59
|
-
├──
|
|
60
|
-
├──
|
|
61
|
-
│
|
|
62
|
-
|
|
63
|
-
│ ├──
|
|
64
|
-
│ │
|
|
65
|
-
│
|
|
66
|
-
│ │
|
|
67
|
-
│ │ ├──
|
|
68
|
-
│ │ │
|
|
69
|
-
│ │
|
|
70
|
-
│ │ ├──
|
|
71
|
-
│ │ │
|
|
72
|
-
│ │
|
|
73
|
-
│ │ ├──
|
|
74
|
-
│ │ │
|
|
75
|
-
│ │
|
|
76
|
-
│ │ ├──
|
|
77
|
-
│ │ │
|
|
78
|
-
│ │
|
|
79
|
-
│ │
|
|
80
|
-
│ │
|
|
81
|
-
│ │
|
|
82
|
-
│ ├──
|
|
83
|
-
│ │
|
|
84
|
-
│
|
|
85
|
-
│ ├──
|
|
86
|
-
│
|
|
87
|
-
│ ├──
|
|
88
|
-
│ ├──
|
|
89
|
-
│ ├──
|
|
90
|
-
│ ├──
|
|
91
|
-
│
|
|
92
|
-
├──
|
|
93
|
-
│
|
|
94
|
-
|
|
95
|
-
│
|
|
96
|
-
├──
|
|
97
|
-
│
|
|
98
|
-
├──
|
|
99
|
-
│ ├──
|
|
100
|
-
│
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
1
|
+
# @robot-admin/layout
|
|
2
|
+
|
|
3
|
+
> 布局和设置管理系统 - 为 Robot Admin 提供完整的布局配置管理能力(含 UI 组件)
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@robot-admin/layout)
|
|
6
|
+
[](https://github.com/ChenyCHENYU/robot-admin-packages/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
当前版本:`3.2.0`。
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## ✨ 特性
|
|
13
|
+
|
|
14
|
+
- 🧠 **智能容器模式** - `C_LayoutContainer` 自动分发布局骨架,主项目只需提供业务插槽
|
|
15
|
+
- 🎨 **6 种布局模式** - 左侧 / 顶部 / 混合 / 顶部混合 / 反转混合 / 卡片布局
|
|
16
|
+
- 🎯 **6 套主题预设** - 科技蓝 / 清新绿 / 商务灰 / 活力橙 / 优雅紫 / 经典红
|
|
17
|
+
- 🧩 **开箱即用** - 提供 SettingsDrawer 设置抽屉,覆盖外观 / 布局 / 功能配置
|
|
18
|
+
- 🧭 **菜单展开方式** - 内置传统展开 / 右侧面板两种菜单展开模式配置
|
|
19
|
+
- 🔌 **插槽系统** - 灵活的 slot 机制,主项目仅关注业务组件
|
|
20
|
+
- 🪄 **精简适配** - `provideLayout()` 从最小宿主输入自动创建完整响应式上下文
|
|
21
|
+
- 🧱 **分层入口** - `core` / `vue` / `naive` 按依赖边界独立消费
|
|
22
|
+
- 🎨 **作用域样式** - 支持带命名空间的 CSS 变量、指定挂载目标与精确清理
|
|
23
|
+
- ♿ **键盘与焦点可访问性** - 抽屉/菜单支持 Escape、方向键、焦点恢复与语义属性
|
|
24
|
+
- 🛡️ **安全设置导入** - 对枚举、布尔值、数值范围与主题色进行运行时校验
|
|
25
|
+
- 🚀 **TypeScript** - 完整类型支持
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 🏗️ 架构设计
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
@robot-admin/layout/core
|
|
33
|
+
└─ 设置协议、校验、常量、纯函数(无运行时依赖)
|
|
34
|
+
|
|
35
|
+
@robot-admin/layout/vue
|
|
36
|
+
└─ Context、Store、Router、Headless Controller(不依赖 UI 组件库)
|
|
37
|
+
|
|
38
|
+
@robot-admin/layout/naive
|
|
39
|
+
└─ 聚合 vue 层 + 现有 6 种布局、响应式菜单、SettingsDrawer(Naive UI 呈现)
|
|
40
|
+
|
|
41
|
+
@robot-admin/layout
|
|
42
|
+
└─ 3.x 兼容入口,继续聚合 vue + naive,不改变历史用法
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
未来 Element Plus 适配只复用 `core` 与 `vue` 层并新增呈现入口,不复制设置事务、菜单测量、
|
|
46
|
+
缓存或六套布局状态逻辑。
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 📁 目录结构
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
src/
|
|
54
|
+
├── index.ts # 主入口(统一导出)
|
|
55
|
+
├── vue/index.ts # Vue Headless 入口(无 UI 库)
|
|
56
|
+
├── naive/index.ts # Naive UI 呈现入口
|
|
57
|
+
├── setup.ts # 一键初始化 setupLayout()
|
|
58
|
+
├── core/ # 无框架设置协议、校验与纯函数
|
|
59
|
+
│ ├── index.ts
|
|
60
|
+
│ ├── settings.ts
|
|
61
|
+
│ └── types.ts
|
|
62
|
+
├── components/
|
|
63
|
+
│ ├── C_LayoutContainer/ # 智能布局容器(主入口组件)
|
|
64
|
+
│ │ └── index.vue
|
|
65
|
+
│ ├── layouts/ # 📐 6 种布局骨架
|
|
66
|
+
│ │ ├── SideLayout/ # C_SideLayout 左侧菜单布局
|
|
67
|
+
│ │ │ ├── index.vue
|
|
68
|
+
│ │ │ └── index.scss
|
|
69
|
+
│ │ ├── TopLayout/ # C_TopLayout 顶部菜单布局
|
|
70
|
+
│ │ │ ├── index.vue
|
|
71
|
+
│ │ │ └── index.scss
|
|
72
|
+
│ │ ├── MixLayout/ # C_MixLayout 左侧混合布局
|
|
73
|
+
│ │ │ ├── index.vue
|
|
74
|
+
│ │ │ └── index.scss
|
|
75
|
+
│ │ ├── MixTopLayout/ # C_MixTopLayout 顶部混合布局
|
|
76
|
+
│ │ │ ├── index.vue
|
|
77
|
+
│ │ │ └── index.scss
|
|
78
|
+
│ │ ├── ReverseHorizontalMixLayout/ # C_ReverseHorizontalMixLayout
|
|
79
|
+
│ │ │ ├── index.vue
|
|
80
|
+
│ │ │ └── index.scss
|
|
81
|
+
│ │ └── CardLayout/ # C_CardLayout 卡片布局
|
|
82
|
+
│ │ ├── index.vue
|
|
83
|
+
│ │ └── index.scss
|
|
84
|
+
│ ├── SettingsDrawer/ # ⚙️ 设置抽屉
|
|
85
|
+
│ │ ├── index.vue
|
|
86
|
+
│ │ └── data.ts
|
|
87
|
+
│ ├── BrandLogo/ # 品牌 Logo
|
|
88
|
+
│ ├── ResponsiveMenu/ # 响应式水平菜单
|
|
89
|
+
│ ├── IconMenu/ # 一级图标菜单
|
|
90
|
+
│ ├── FloatingMenu/ # 悬浮二级菜单
|
|
91
|
+
│ ├── SideMenu/ # 右侧二级菜单
|
|
92
|
+
│ ├── DrawerMenu/ # 抽屉式网格菜单
|
|
93
|
+
│ └── MenuTrigger/ # 菜单触发区域
|
|
94
|
+
├── composables/
|
|
95
|
+
│ ├── useLayoutContext.ts # LayoutContext provide/inject
|
|
96
|
+
│ ├── createLayoutContext.ts # 最小宿主输入适配助手
|
|
97
|
+
│ ├── useLayoutCssVariables.ts # 作用域 CSS 变量绑定
|
|
98
|
+
│ ├── useResponsiveMenu.ts # UI 无关的菜单测量
|
|
99
|
+
│ ├── useSettingsController.ts # UI 无关的设置事务与副作用
|
|
100
|
+
│ ├── useLayoutCache.ts # 页面缓存管理
|
|
101
|
+
│ └── useMenuSplit.ts # 菜单拆分(一级/二级分离)
|
|
102
|
+
├── utils/menu.ts # 宿主菜单标准化
|
|
103
|
+
├── stores/
|
|
104
|
+
│ └── settings.ts # 布局设置 Pinia Store
|
|
105
|
+
├── styles/
|
|
106
|
+
│ ├── layouts.scss # 布局骨架公共样式
|
|
107
|
+
│ └── settings.scss # 设置组件样式
|
|
108
|
+
├── constants/
|
|
109
|
+
│ └── index.ts # 预设常量
|
|
110
|
+
└── types/
|
|
111
|
+
├── index.ts # 类型定义
|
|
112
|
+
└── menu.ts # 菜单类型
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 📦 安装
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
bun add @robot-admin/layout naive-ui
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Peer Dependencies**: `vue ^3.4` · `vue-router ^4.0` · `pinia ^2.0 || ^3.0`。
|
|
124
|
+
`naive-ui ^2.38` 仅在使用根入口或 `/naive` 时需要,并已声明为 optional peer。
|
|
125
|
+
|
|
126
|
+
> `@robot-admin/layout/vue` 不导入 Naive UI 或 Element Plus。当前版本建立了双 UI 适配边界,
|
|
127
|
+
> 但尚未发布 Element Plus 呈现组件,避免在没有真实项目验证时制造第二套未使用 UI。
|
|
128
|
+
|
|
129
|
+
### 入口选择
|
|
130
|
+
|
|
131
|
+
| 使用场景 | 唯一推荐入口 | 说明 |
|
|
132
|
+
| ---------------------------- | ----------------------------- | ------------------------------------- |
|
|
133
|
+
| 新建或升级 Naive UI 项目 | `@robot-admin/layout/naive` | 聚合组件、Store、Context 和工具 |
|
|
134
|
+
| Element Plus 项目复用布局逻辑 | `@robot-admin/layout/vue` | 无 UI 库依赖,视图暂由宿主实现 |
|
|
135
|
+
| Node/服务端只处理设置协议 | `@robot-admin/layout/core` | 无 Vue、Pinia、Router 和 UI 运行时 |
|
|
136
|
+
| 现有 3.x 项目 | `@robot-admin/layout` | 兼容入口,可继续使用,不要求立即迁移 |
|
|
120
137
|
|
|
121
138
|
---
|
|
122
|
-
|
|
123
|
-
## 🚀 快速开始
|
|
124
|
-
|
|
125
|
-
### 1. 初始化
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
// main.ts
|
|
129
|
-
import { createApp } from "vue";
|
|
130
|
-
import { createPinia } from "pinia";
|
|
131
|
-
import { setupLayout } from "@robot-admin/layout";
|
|
132
|
-
import "@robot-admin/layout/style"; //
|
|
133
|
-
import App from "./App.vue";
|
|
134
|
-
|
|
135
|
-
const app = createApp(App);
|
|
136
|
-
app.use(createPinia());
|
|
137
|
-
|
|
138
|
-
setupLayout(app, {
|
|
139
|
-
// 可选:同步到宿主自己的主题系统
|
|
140
|
-
onThemeModeChange: (mode) => syncAppTheme(mode),
|
|
141
|
-
defaults: {
|
|
142
|
-
layoutMode: "side",
|
|
143
|
-
primaryColor: "#409eff",
|
|
144
|
-
},
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
app.mount("#app");
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### 2.
|
|
151
|
-
|
|
152
|
-
```vue
|
|
153
|
-
|
|
154
|
-
<
|
|
155
|
-
|
|
156
|
-
<template #
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
/></template>
|
|
160
|
-
<template #
|
|
161
|
-
<template #
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
|
288
|
-
|
|
|
289
|
-
|
|
|
290
|
-
|
|
|
291
|
-
|
|
|
292
|
-
|
|
|
293
|
-
|
|
|
294
|
-
|
|
|
295
|
-
|
|
|
296
|
-
|
|
|
297
|
-
|
|
|
298
|
-
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
139
|
+
|
|
140
|
+
## 🚀 快速开始
|
|
141
|
+
|
|
142
|
+
### 1. 初始化
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// main.ts
|
|
146
|
+
import { createApp } from "vue";
|
|
147
|
+
import { createPinia } from "pinia";
|
|
148
|
+
import { setupLayout } from "@robot-admin/layout/naive";
|
|
149
|
+
import "@robot-admin/layout/naive/style"; // Naive UI 布局样式
|
|
150
|
+
import App from "./App.vue";
|
|
151
|
+
|
|
152
|
+
const app = createApp(App);
|
|
153
|
+
app.use(createPinia());
|
|
154
|
+
|
|
155
|
+
setupLayout(app, {
|
|
156
|
+
// 可选:同步到宿主自己的主题系统
|
|
157
|
+
onThemeModeChange: (mode) => syncAppTheme(mode),
|
|
158
|
+
defaults: {
|
|
159
|
+
layoutMode: "side",
|
|
160
|
+
primaryColor: "#409eff",
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
app.mount("#app");
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 2. 提供宿主数据并使用布局容器
|
|
168
|
+
|
|
169
|
+
```vue
|
|
170
|
+
<template>
|
|
171
|
+
<C_LayoutContainer>
|
|
172
|
+
<template #logo><AppLogo /></template>
|
|
173
|
+
<template #menu="{ collapsed }"
|
|
174
|
+
><AppMenu :collapsed="collapsed"
|
|
175
|
+
/></template>
|
|
176
|
+
<template #header><AppHeader /></template>
|
|
177
|
+
<template #tags-view><AppTags /></template>
|
|
178
|
+
<template #footer><AppFooter /></template>
|
|
179
|
+
</C_LayoutContainer>
|
|
180
|
+
</template>
|
|
181
|
+
|
|
182
|
+
<script setup lang="ts">
|
|
183
|
+
import {
|
|
184
|
+
C_LayoutContainer,
|
|
185
|
+
provideLayout,
|
|
186
|
+
useSettingsStore,
|
|
187
|
+
type MenuOptions,
|
|
188
|
+
} from "@robot-admin/layout/naive";
|
|
189
|
+
|
|
190
|
+
const props = defineProps<{
|
|
191
|
+
menus: MenuOptions[];
|
|
192
|
+
isDark: boolean;
|
|
193
|
+
}>();
|
|
194
|
+
|
|
195
|
+
provideLayout({
|
|
196
|
+
settings: useSettingsStore(),
|
|
197
|
+
menus: () => props.menus,
|
|
198
|
+
isDark: () => props.isDark,
|
|
199
|
+
brand: { name: "My Admin", homePath: "/home" },
|
|
200
|
+
});
|
|
201
|
+
</script>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`provideLayout()` 会自动桥接布局模式、折叠状态、尺寸、动画和显示开关。只有需要完全
|
|
205
|
+
自定义响应式来源时,才直接构造 `LayoutContext` 并调用 `provideLayoutContext()`。
|
|
206
|
+
|
|
207
|
+
### 3. 添加设置抽屉
|
|
208
|
+
|
|
209
|
+
```vue
|
|
210
|
+
<script setup lang="ts">
|
|
211
|
+
import { ref } from "vue";
|
|
212
|
+
import { NDialogProvider, NMessageProvider } from "naive-ui";
|
|
213
|
+
import { SettingsDrawer } from "@robot-admin/layout/naive";
|
|
214
|
+
|
|
215
|
+
const visible = ref(false);
|
|
216
|
+
const settingsActions = {
|
|
217
|
+
clearCache: () => localStorage.removeItem("my-app-disposable-cache"),
|
|
218
|
+
};
|
|
219
|
+
</script>
|
|
220
|
+
|
|
221
|
+
<template>
|
|
222
|
+
<button @click="visible = true">⚙️ 设置</button>
|
|
223
|
+
<NDialogProvider>
|
|
224
|
+
<NMessageProvider>
|
|
225
|
+
<SettingsDrawer v-model:show="visible" :actions="settingsActions">
|
|
226
|
+
<template #appearance-prepend>
|
|
227
|
+
<AppThemeExtension />
|
|
228
|
+
</template>
|
|
229
|
+
</SettingsDrawer>
|
|
230
|
+
</NMessageProvider>
|
|
231
|
+
</NDialogProvider>
|
|
232
|
+
</template>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
`SettingsDrawer` 使用 Naive UI 的 Message/Dialog API,因此必须位于
|
|
236
|
+
`NMessageProvider` 和 `NDialogProvider` 下;应用根部已有 Provider 时无需重复包裹。
|
|
237
|
+
|
|
238
|
+
`SettingsDrawer` 不再自行清空 `localStorage` / `sessionStorage`。缓存清理由宿主通过
|
|
239
|
+
`actions.clearCache` 明确实现,避免误删登录态、语言和业务数据。可用扩展插槽:
|
|
240
|
+
`appearance-prepend/append`、`layout-prepend/after-mode/append`、
|
|
241
|
+
`features-prepend/append`;插槽均暴露当前 `settings`。
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## 📐 布局模式
|
|
246
|
+
|
|
247
|
+
| 模式 | 常量值 | 一级菜单 | 二级菜单 | 适用场景 |
|
|
248
|
+
| ------------ | ------------------------ | ---------- | -------------- | ------------------------ |
|
|
249
|
+
| **左侧菜单** | `side` | 左侧栏 | 左侧栏(折叠) | 经典后台管理(ERP、CRM) |
|
|
250
|
+
| **顶部菜单** | `top` | 顶部横向 | 顶部下拉 | 菜单少,需更宽内容区 |
|
|
251
|
+
| **混合布局** | `mix` | 左侧图标栏 | 悬浮弹出 | 一级菜单少,二级多 |
|
|
252
|
+
| **顶部混合** | `mix-top` | 左侧图标栏 | 顶部横向 | 全局导航 + 侧边详情 |
|
|
253
|
+
| **反转混合** | `reverse-horizontal-mix` | 顶部横向 | 右侧栏 | 特殊需求,右手操作 |
|
|
254
|
+
| **卡片布局** | `card-layout` | hover 抽屉 | 网格铺开 | 应用首页 / 工作台 |
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## 🎨 主题预设
|
|
259
|
+
|
|
260
|
+
| 预设 | 主题色 | 图标 |
|
|
261
|
+
| ------ | --------- | ---- |
|
|
262
|
+
| 科技蓝 | `#409eff` | 💙 |
|
|
263
|
+
| 清新绿 | `#52c41a` | 💚 |
|
|
264
|
+
| 商务灰 | `#595959` | 🖤 |
|
|
265
|
+
| 活力橙 | `#fa8c16` | 🧡 |
|
|
266
|
+
| 优雅紫 | `#722ed1` | 💜 |
|
|
267
|
+
| 经典红 | `#f5222d` | ❤️ |
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## ⚙️ Store API
|
|
272
|
+
|
|
273
|
+
### `useSettingsStore()`
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import { useSettingsStore } from "@robot-admin/layout/vue";
|
|
277
|
+
|
|
278
|
+
const settings = useSettingsStore();
|
|
279
|
+
|
|
280
|
+
// 读取
|
|
281
|
+
settings.layoutMode; // 'side' | 'top' | 'mix' | ...
|
|
282
|
+
settings.menuExpandMode; // 'inline' | 'panel'
|
|
283
|
+
settings.primaryColor; // '#409eff'
|
|
284
|
+
settings.themeMode; // 'light' | 'dark' | 'system'
|
|
285
|
+
|
|
286
|
+
// 修改
|
|
287
|
+
settings.layoutMode = "mix";
|
|
288
|
+
settings.menuExpandMode = "panel";
|
|
289
|
+
settings.updateThemeMode("dark");
|
|
290
|
+
settings.applyPreset(THEME_PRESETS[0]);
|
|
291
|
+
settings.resetSettings();
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### 设置属性一览
|
|
295
|
+
|
|
296
|
+
| 属性 | 默认值 | 作用方 | 说明 |
|
|
297
|
+
| ----------------------- | ----------- | ---------- | ------------------------------------ |
|
|
298
|
+
| `themeMode` | `'light'` | 宿主回调 | 标准主题模式 |
|
|
299
|
+
| `primaryColor` | `'#409eff'` | 包内 | 主题色与派生 CSS 变量 |
|
|
300
|
+
| `borderRadius` | `'medium'` | 包内 | 圆角 CSS 变量 |
|
|
301
|
+
| `transitionType` | `'slide'` | 包内 | 页面动画类型 |
|
|
302
|
+
| `enableTransition` | `true` | 包内 | 是否启用页面动画 |
|
|
303
|
+
| `layoutMode` | `'side'` | 包内 | 当前布局模式 |
|
|
304
|
+
| `menuExpandMode` | `'inline'` | 宿主菜单 | 菜单展开方式 |
|
|
305
|
+
| `collapsed` | `false` | 包内/宿主 | 共享侧栏折叠状态 |
|
|
306
|
+
| `fixedHeader` | `true` | 宿主头部 | 固定头部策略 |
|
|
307
|
+
| `showBreadcrumb` | `true` | 宿主头部 | 显示面包屑 |
|
|
308
|
+
| `showBreadcrumbIcon` | `true` | 宿主头部 | 显示面包屑图标 |
|
|
309
|
+
| `showTagsView` | `true` | 包内 | 显示标签页 |
|
|
310
|
+
| `tagsViewHeight` | `44` | 包内 | 标签页高度 (px) |
|
|
311
|
+
| `tagsViewStyle` | `'default'` | 宿主标签页 | 标签页风格 |
|
|
312
|
+
| `showFooter` | `true` | 包内 | 显示页脚 |
|
|
313
|
+
| `sidebarWidth` | `220` | 包内 | 侧边栏宽度 (px) |
|
|
314
|
+
| `sidebarCollapsedWidth` | `64` | 包内 | 折叠宽度 (px) |
|
|
315
|
+
| `headerHeight` | `56` | 包内/宿主 | 头部高度 (px) |
|
|
316
|
+
| `enableHotkeys` | `true` | 宿主扩展 | 是否启用宿主快捷键 |
|
|
317
|
+
| `version` | `'3.2.0'` | 兼容字段 | 已废弃;配置迁移请使用 schemaVersion |
|
|
318
|
+
|
|
319
|
+
“宿主”字段由 Store 和导入导出协议统一维护,但布局包不会越权修改宿主业务组件;这种边界
|
|
320
|
+
避免重复实现面包屑、快捷键和标签页等业务能力。
|
|
321
|
+
|
|
322
|
+
### CSS 变量
|
|
323
|
+
|
|
324
|
+
默认 Store 同时维护带命名空间的新变量与 3.x 兼容变量:
|
|
325
|
+
|
|
326
|
+
```css
|
|
327
|
+
--ra-layout-primary-color: #409eff;
|
|
328
|
+
--ra-layout-primary-color-hover: #4aa8ff;
|
|
329
|
+
--ra-layout-primary-color-pressed: #368af5;
|
|
330
|
+
--ra-layout-sidebar-width: 220px;
|
|
331
|
+
--ra-layout-sidebar-collapsed-width: 64px;
|
|
332
|
+
--ra-layout-header-height: 56px;
|
|
333
|
+
--ra-layout-tags-view-height: 44px;
|
|
334
|
+
--ra-layout-border-radius: 6px;
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
微前端或嵌入式页面可以关闭默认根节点同步,并绑定到自己的容器;`dispose()` 会恢复目标原值:
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import {
|
|
341
|
+
bindLayoutCssVariables,
|
|
342
|
+
createSettingsStore,
|
|
343
|
+
} from "@robot-admin/layout/vue";
|
|
344
|
+
|
|
345
|
+
const settings = createSettingsStore({
|
|
346
|
+
id: "workspace-settings",
|
|
347
|
+
syncCssVariables: false,
|
|
348
|
+
})();
|
|
349
|
+
const cssBinding = bindLayoutCssVariables(settings, {
|
|
350
|
+
target: document.querySelector("#workspace"),
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
// 微前端卸载时
|
|
354
|
+
cssBinding.dispose();
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## 🧩 C_LayoutContainer Slots
|
|
360
|
+
|
|
361
|
+
| Slot 名称 | 说明 | 适用布局 |
|
|
362
|
+
| --------------- | -------------- | ----------------------------- |
|
|
363
|
+
| `#logo` | 品牌 Logo | 全部 |
|
|
364
|
+
| `#menu` | 垂直菜单 | Side |
|
|
365
|
+
| `#header` | 完整头部 | Side / Mix |
|
|
366
|
+
| `#header-extra` | 头部右侧操作区 | Top / MixTop / Reverse / Card |
|
|
367
|
+
| `#top-menu` | 水平菜单 | Top / MixTop / Reverse |
|
|
368
|
+
| `#tags-view` | 标签页 | 全部 |
|
|
369
|
+
| `#footer` | 页脚 | 全部 |
|
|
370
|
+
| `#brand` | 顶部品牌区 | MixTop |
|
|
371
|
+
| `#menu-trigger` | 菜单触发区 | Card |
|
|
372
|
+
| `#drawer-menu` | 抽屉菜单 | Card |
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## 📖 类型定义
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
type LayoutMode =
|
|
380
|
+
"side" | "top" | "mix" | "mix-top" | "reverse-horizontal-mix" | "card-layout";
|
|
381
|
+
type MenuExpandMode = "inline" | "panel";
|
|
382
|
+
type TransitionType = "fade" | "slide" | "zoom" | "none";
|
|
383
|
+
type BorderRadiusSize = "small" | "medium" | "large";
|
|
384
|
+
type TagsViewStyle = "default" | "card" | "smart";
|
|
385
|
+
type ThemeMode = "light" | "dark" | "system";
|
|
386
|
+
|
|
387
|
+
interface ThemePreset {
|
|
388
|
+
name: string;
|
|
389
|
+
icon: string;
|
|
390
|
+
primaryColor: string;
|
|
391
|
+
}
|
|
392
|
+
interface SettingsStoreOptions {
|
|
393
|
+
id?: string;
|
|
394
|
+
defaults?: Partial<SettingsState>;
|
|
395
|
+
onThemeModeChange?: (mode: ThemeMode) => void | Promise<void>;
|
|
396
|
+
syncCssVariables?: boolean;
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## 🔧 高级用法
|
|
403
|
+
|
|
404
|
+
### 自定义 Settings Store
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
import { createSettingsStore } from "@robot-admin/layout/vue";
|
|
408
|
+
|
|
409
|
+
export const useSettingsStore = createSettingsStore({
|
|
410
|
+
// 多实例或微前端中必须保证唯一;单实例可省略
|
|
411
|
+
id: "workspace-settings",
|
|
412
|
+
defaults: { layoutMode: "mix", primaryColor: "#722ed1" },
|
|
413
|
+
onThemeModeChange: async (mode) => {
|
|
414
|
+
const themeStore = useThemeStore();
|
|
415
|
+
await themeStore.setMode(mode);
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### 校验外部设置
|
|
421
|
+
|
|
422
|
+
从文件、URL 或远端接口加载的设置属于不可信输入,写入 Store 前应先校验:
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import { sanitizeLayoutSettingsConfig } from "@robot-admin/layout/core";
|
|
426
|
+
import { useSettingsStore } from "@robot-admin/layout/vue";
|
|
427
|
+
|
|
428
|
+
const imported = JSON.parse(await file.text());
|
|
429
|
+
// 一次校验完整文件,失败时不会产生部分状态写入。
|
|
430
|
+
const config = sanitizeLayoutSettingsConfig(imported);
|
|
431
|
+
const safePatch = config.settings ?? {};
|
|
432
|
+
const settings = useSettingsStore();
|
|
433
|
+
|
|
434
|
+
if (safePatch.themeMode !== undefined) {
|
|
435
|
+
await settings.updateThemeMode(safePatch.themeMode);
|
|
436
|
+
delete safePatch.themeMode;
|
|
437
|
+
}
|
|
438
|
+
settings.$patch(safePatch);
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
未知字段会被忽略以便向前兼容;已知字段类型错误、越界值、非法主题色或旧的
|
|
442
|
+
`themeMode: "auto"` 会抛出明确错误。设置抽屉内置的导入功能已执行同一校验。
|
|
443
|
+
|
|
444
|
+
`useLayoutCache()` 默认不会输出开发日志,也不会向 `window` 暴露调试函数;仅在
|
|
445
|
+
受控的本地开发场景显式设置 `enableDevLog` / `exposeToWindow`。
|
|
446
|
+
|
|
447
|
+
### `C_*Layout` 命名约定
|
|
448
|
+
|
|
449
|
+
`C_LayoutContainer`、`C_SideLayout`、`C_TopLayout` 等是唯一推荐、持续维护的公开组件名称,
|
|
450
|
+
与 Robot_Admin 的全局公共组件规范一致。无前缀名称不再作为第二套用法出现在示例中;它们只为
|
|
451
|
+
已发布的 3.1 消费方保留为带 `@deprecated` 标记的 3.x 兼容出口,并指向同一个组件对象,
|
|
452
|
+
不会产生第二份实现。新代码统一使用 `C_*`,4.0 再删除无前缀兼容名称。
|
|
453
|
+
|
|
454
|
+
### 3.2 升级说明
|
|
455
|
+
|
|
456
|
+
- 新增 `/vue` 与 `/naive` 独立入口;`/naive` 聚合 Vue Headless 能力,Naive 项目只需一个
|
|
457
|
+
脚本入口,3.x 根入口继续完全兼容。
|
|
458
|
+
- `createLayoutContext()` 改为依赖结构化 `LayoutSettingsSource`,可接入包内 Pinia Store、
|
|
459
|
+
宿主 Store 或其他 Vue 响应式状态。
|
|
460
|
+
- 新增 `useSettingsController()`、`useResponsiveMenu()`、`normalizeLayoutMenus()` 和
|
|
461
|
+
`bindLayoutCssVariables()`,供其他 UI 适配器复用。
|
|
462
|
+
- SettingsDrawer 已复用 Headless controller,自定义 Store 的局部重置会恢复该实例自己的默认值。
|
|
463
|
+
- 布局样式、动画名和新 CSS 变量使用 `ra-layout` 边界;旧 CSS 变量在 3.x 继续同步。
|
|
464
|
+
- `C_SideLayout` 等 `C_*Layout` 重新确立为唯一正式组件名称;无前缀名称仅作为带
|
|
465
|
+
`@deprecated` 标记的 3.x 兼容出口,4.0 移除。
|
|
466
|
+
|
|
467
|
+
### 3.1 升级说明
|
|
468
|
+
|
|
469
|
+
- 新增 `createLayoutContext()` 与 `provideLayout()`,用于精简普通项目的上下文桥接代码。
|
|
470
|
+
- 原有 `LayoutContext`、`provideLayoutContext()` 和所有组件/插槽继续兼容。
|
|
471
|
+
- 3.1 曾建议从 `C_*Layout` 迁移到无前缀名称;3.2 已根据项目统一命名规范纠正该策略。
|
|
472
|
+
|
|
473
|
+
### 3.0 升级说明
|
|
474
|
+
|
|
475
|
+
- 现有根入口、6 种布局、组件名、slot 名和 CSS 入口保持兼容。
|
|
476
|
+
- `LayoutContext.collapsed` 为可选的双向状态;提供后,侧栏与宿主头部共享同一折叠状态。
|
|
477
|
+
- 自定义 Store 可通过 `setupLayout()` 注入,也可用 `SettingsDrawer :store="store"` 显式传入。
|
|
478
|
+
- `enableTransition: false` 现在会真正关闭路由过渡,但保留已选择的动画类型。
|
|
479
|
+
- 缓存清理改为宿主白名单动作;从 2.x 升级时请传入 `actions.clearCache`。
|
|
480
|
+
- `@robot-admin/theme` 不再是 peer dependency;需要主题联动时使用 `onThemeModeChange`。
|
|
481
|
+
|
|
482
|
+
多 Store 实例可以拥有独立状态。CSS 变量可通过 `bindLayoutCssVariables()` 隔离到宿主容器;
|
|
483
|
+
设置抽屉也已支持由 adapter controller 指定视觉根节点和水印容器。默认值仍保持页面级行为,
|
|
484
|
+
保证 3.x 现有项目无迁移成本。
|
|
485
|
+
|
|
486
|
+
### 单独使用布局骨架
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
import {
|
|
490
|
+
C_SideLayout,
|
|
491
|
+
C_TopLayout,
|
|
492
|
+
C_MixLayout,
|
|
493
|
+
} from "@robot-admin/layout/naive";
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
> ⚠️ 直接使用骨架组件需自行提供 `LayoutContext`(通过 `provide`),推荐使用 `C_LayoutContainer`
|
|
497
|
+
|
|
498
|
+
### 样式导入方式
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
// 方式 1:编译后 CSS(推荐)
|
|
502
|
+
import "@robot-admin/layout/naive/style";
|
|
503
|
+
|
|
504
|
+
// 方式 2:SCSS 源文件(可定制)
|
|
505
|
+
import "@robot-admin/layout/style.scss";
|
|
506
|
+
|
|
507
|
+
// 方式 3:仅布局骨架基础样式
|
|
508
|
+
import "@robot-admin/layout/layouts.scss";
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
## 🔗 相关链接
|
|
514
|
+
|
|
515
|
+
- [Robot Admin 主项目](https://github.com/ChenyCHENYU/Robot_Admin)
|
|
516
|
+
- [@robot-admin/theme](https://www.npmjs.com/package/@robot-admin/theme)
|
|
517
|
+
- [Naive UI](https://www.naiveui.com/)
|
|
518
|
+
|
|
519
|
+
## 📄 License
|
|
520
|
+
|
|
521
|
+
MIT © ChenYu
|