@robot-admin/layout 0.1.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/README.md +635 -0
- package/dist/index.cjs +39 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +427 -0
- package/dist/index.js +888 -0
- package/dist/index.js.map +1 -0
- package/package.json +67 -0
- package/src/styles/settings.scss +380 -0
package/README.md
ADDED
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
# @robot-admin/layout
|
|
2
|
+
|
|
3
|
+
> 布局和设置管理系统 - 为 Robot Admin 提供完整的布局配置管理能力(含 UI 组件)
|
|
4
|
+
|
|
5
|
+
## ✨ 特性
|
|
6
|
+
|
|
7
|
+
- 🎨 **多布局支持** - 左侧/顶部/混合等 6 种布局模式
|
|
8
|
+
- 🎯 **主题预设** - 内置 6 套精美主题预设方案
|
|
9
|
+
- 🧩 **开箱即用** - 提供完整的设置抽屉 UI 组件
|
|
10
|
+
- ⚙️ **丰富配置** - 面包屑、标签页、页脚等多维度配置
|
|
11
|
+
- 🎨 **样式灵活** - 支持 SCSS 源文件或编译后 CSS
|
|
12
|
+
- 💾 **持久化存储** - 自动保存用户配置偏好
|
|
13
|
+
- 🔧 **高度可配置** - 灵活的初始化选项
|
|
14
|
+
- 🚀 **TypeScript** - 完整的类型支持
|
|
15
|
+
|
|
16
|
+
## 📦 安装
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @robot-admin/layout @robot-admin/theme naive-ui
|
|
20
|
+
# or
|
|
21
|
+
pnpm add @robot-admin/layout @robot-admin/theme naive-ui
|
|
22
|
+
# or
|
|
23
|
+
bun add @robot-admin/layout @robot-admin/theme naive-ui
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**依赖说明**:
|
|
27
|
+
|
|
28
|
+
- `@robot-admin/theme` - 主题管理系统(必需)
|
|
29
|
+
- `naive-ui` - UI 组件库(必需,用于 SettingsDrawer)
|
|
30
|
+
- `vue` - Vue 3.4+
|
|
31
|
+
- `pinia` - 状态管理
|
|
32
|
+
|
|
33
|
+
## 🚀 快速开始
|
|
34
|
+
|
|
35
|
+
### 方式一:使用 setupLayout(推荐)
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// main.ts
|
|
39
|
+
import { createApp } from "vue";
|
|
40
|
+
import { createPinia } from "pinia";
|
|
41
|
+
import { setupLayout } from "@robot-admin/layout";
|
|
42
|
+
import { useThemeStore } from "@robot-admin/theme";
|
|
43
|
+
import "@robot-admin/layout/style.scss"; // 或 style.css
|
|
44
|
+
import App from "./App.vue";
|
|
45
|
+
|
|
46
|
+
const app = createApp(App);
|
|
47
|
+
const pinia = createPinia();
|
|
48
|
+
app.use(pinia);
|
|
49
|
+
|
|
50
|
+
// 初始化主题系统
|
|
51
|
+
const themeStore = useThemeStore();
|
|
52
|
+
themeStore.init();
|
|
53
|
+
|
|
54
|
+
// 初始化布局系统(自动同步 theme store)
|
|
55
|
+
setupLayout(app, {
|
|
56
|
+
onThemeModeChange: async (mode) => {
|
|
57
|
+
await themeStore.setMode(mode);
|
|
58
|
+
},
|
|
59
|
+
defaults: {
|
|
60
|
+
layoutMode: "side",
|
|
61
|
+
primaryColor: "#409eff",
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
app.mount("#app");
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 方式二:手动初始化
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// main.ts
|
|
72
|
+
import { createApp } from "vue";
|
|
73
|
+
import { createPinia } from "pinia";
|
|
74
|
+
import { useThemeStore } from "@robot-admin/theme";
|
|
75
|
+
import { useSettingsStore } from "@robot-admin/layout";
|
|
76
|
+
import App from "./App.vue";
|
|
77
|
+
|
|
78
|
+
const app = createApp(App);
|
|
79
|
+
const pinia = createPinia();
|
|
80
|
+
app.use(pinia);
|
|
81
|
+
|
|
82
|
+
// 初始化主题系统
|
|
83
|
+
const themeStore = useThemeStore();
|
|
84
|
+
themeStore.init();
|
|
85
|
+
|
|
86
|
+
// 初始化设置系统
|
|
87
|
+
const settingsStore = useSettingsStore();
|
|
88
|
+
settingsStore.syncCSSVariables();
|
|
89
|
+
|
|
90
|
+
app.mount("#app");
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 🎨 样式导入
|
|
94
|
+
|
|
95
|
+
### 使用 SCSS(推荐,可定制)
|
|
96
|
+
|
|
97
|
+
```scss
|
|
98
|
+
// 全局 SCSS 文件
|
|
99
|
+
@import "@robot-admin/layout/style.scss";
|
|
100
|
+
|
|
101
|
+
// 可以覆盖变量
|
|
102
|
+
:root {
|
|
103
|
+
--app-primary: #409eff;
|
|
104
|
+
--app-border-light: #e5e7eb;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 使用编译后的 CSS
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// main.ts 或组件中
|
|
112
|
+
import "@robot-admin/layout/style.css";
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 🧩 UI 组件使用
|
|
116
|
+
|
|
117
|
+
### SettingsDrawer - 设置抽屉
|
|
118
|
+
|
|
119
|
+
完整的布局配置 UI,包含外观/布局/功能三大模块
|
|
120
|
+
|
|
121
|
+
```vue
|
|
122
|
+
<template>
|
|
123
|
+
<div>
|
|
124
|
+
<!-- 触发按钮 -->
|
|
125
|
+
<button @click="visible = true">⚙️ 打开设置</button>
|
|
126
|
+
|
|
127
|
+
<!-- 设置抽屉 -->
|
|
128
|
+
<SettingsDrawer v-model:show="visible" storage-key="my-app-settings" />
|
|
129
|
+
</div>
|
|
130
|
+
</template>
|
|
131
|
+
|
|
132
|
+
<script setup lang="ts">
|
|
133
|
+
import { ref } from "vue";
|
|
134
|
+
import { SettingsDrawer } from "@robot-admin/layout";
|
|
135
|
+
|
|
136
|
+
const visible = ref(false);
|
|
137
|
+
</script>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### Props
|
|
141
|
+
|
|
142
|
+
- `show` - 控制抽屉显示/隐藏(支持 v-model)
|
|
143
|
+
- `storageKey` - localStorage 存储键名(可选,默认 'robot-admin-settings')
|
|
144
|
+
|
|
145
|
+
#### 功能模块
|
|
146
|
+
|
|
147
|
+
**外观 Tab 🎨**
|
|
148
|
+
|
|
149
|
+
- 6 种主题预设方案(科技蓝/清新绿/商务灰等)
|
|
150
|
+
- 主题模式切换(亮色/暗色/跟随系统)
|
|
151
|
+
- 主题色选择器(支持预设色板)
|
|
152
|
+
- 圆角大小调节(小/中/大)
|
|
153
|
+
- 页面动画效果(淡入/滑动/缩放/无动画)
|
|
154
|
+
|
|
155
|
+
**布局 Tab 📐**
|
|
156
|
+
|
|
157
|
+
- 6 种布局模式切换(左侧/顶部/混合/卡片等)
|
|
158
|
+
- 固定头部开关
|
|
159
|
+
- 面包屑显示/图标配置
|
|
160
|
+
- 标签页样式(默认/卡片/智能)
|
|
161
|
+
- 侧边栏宽度调节
|
|
162
|
+
- 页脚显示开关
|
|
163
|
+
|
|
164
|
+
**功能 Tab ⚙️**
|
|
165
|
+
|
|
166
|
+
- 缓存管理(清除全部/仅首页/其他)
|
|
167
|
+
- 配置导入/导出(JSON)
|
|
168
|
+
- 重置所有配置
|
|
169
|
+
- 水印显示开关
|
|
170
|
+
- 灰色模式/色弱模式
|
|
171
|
+
- 系统信息展示(浏览器/OS/分辨率等)
|
|
172
|
+
|
|
173
|
+
## 📚 API 文档
|
|
174
|
+
|
|
175
|
+
### Store
|
|
176
|
+
|
|
177
|
+
#### `createSettingsStore(options?)`
|
|
178
|
+
|
|
179
|
+
创建自定义配置的设置 Store
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { createSettingsStore } from "@robot-admin/layout";
|
|
183
|
+
|
|
184
|
+
const useSettingsStore = createSettingsStore({
|
|
185
|
+
defaults: {
|
|
186
|
+
layoutMode: "side", // 默认布局
|
|
187
|
+
primaryColor: "#409eff", // 默认主题色
|
|
188
|
+
showTagsView: true, // 显示标签页
|
|
189
|
+
fixedHeader: true, // 固定头部
|
|
190
|
+
},
|
|
191
|
+
storageKey: "my-app-settings", // localStorage 键名
|
|
192
|
+
onThemeModeChange: async (mode) => {
|
|
193
|
+
// 主题模式变化回调(同步到 theme store)
|
|
194
|
+
const themeStore = useThemeStore();
|
|
195
|
+
await themeStore.setMode(mode);
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**参数类型:**
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
interface SettingsStoreOptions {
|
|
204
|
+
defaults?: Partial<SettingsState>;
|
|
205
|
+
storageKey?: string;
|
|
206
|
+
onThemeModeChange?: (mode: ThemeMode) => void | Promise<void>;
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### `useSettingsStore()`
|
|
211
|
+
|
|
212
|
+
获取默认的设置 Store 实例
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
import { useSettingsStore } from "@robot-admin/layout";
|
|
216
|
+
|
|
217
|
+
const settingsStore = useSettingsStore();
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Store 属性
|
|
221
|
+
|
|
222
|
+
#### 外观设置
|
|
223
|
+
|
|
224
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
225
|
+
| ------------------ | ------------------ | ----------- | ------------------------------ |
|
|
226
|
+
| `themeMode` | `ThemeMode` | `'system'` | 主题模式(light/dark/system) |
|
|
227
|
+
| `primaryColor` | `string` | `'#409eff'` | 主题色 |
|
|
228
|
+
| `borderRadius` | `BorderRadiusSize` | `'medium'` | 圆角大小(small/medium/large) |
|
|
229
|
+
| `transitionType` | `TransitionType` | `'fade'` | 页面动画类型 |
|
|
230
|
+
| `enableTransition` | `boolean` | `true` | 启用页面动画 |
|
|
231
|
+
|
|
232
|
+
#### 布局设置
|
|
233
|
+
|
|
234
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
235
|
+
| ----------------------- | --------------- | ----------- | -------------------- |
|
|
236
|
+
| `layoutMode` | `LayoutMode` | `'side'` | 布局模式 |
|
|
237
|
+
| `fixedHeader` | `boolean` | `true` | 固定头部 |
|
|
238
|
+
| `showBreadcrumb` | `boolean` | `true` | 显示面包屑 |
|
|
239
|
+
| `showBreadcrumbIcon` | `boolean` | `true` | 显示面包屑图标 |
|
|
240
|
+
| `showTagsView` | `boolean` | `true` | 显示标签页 |
|
|
241
|
+
| `tagsViewHeight` | `number` | `40` | 标签页高度(px) |
|
|
242
|
+
| `tagsViewStyle` | `TagsViewStyle` | `'default'` | 标签页风格 |
|
|
243
|
+
| `showFooter` | `boolean` | `false` | 显示页脚 |
|
|
244
|
+
| `sidebarWidth` | `number` | `220` | 侧边栏宽度(px) |
|
|
245
|
+
| `sidebarCollapsedWidth` | `number` | `64` | 侧边栏折叠宽度(px) |
|
|
246
|
+
| `headerHeight` | `number` | `56` | 头部高度(px) |
|
|
247
|
+
|
|
248
|
+
#### 功能设置
|
|
249
|
+
|
|
250
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
251
|
+
| --------------------- | --------- | --------------- | -------- |
|
|
252
|
+
| `enableWatermark` | `boolean` | `false` | 启用水印 |
|
|
253
|
+
| `watermarkText` | `string` | `'Robot Admin'` | 水印文本 |
|
|
254
|
+
| `enableGrayMode` | `boolean` | `false` | 灰色模式 |
|
|
255
|
+
| `enableColorWeakMode` | `boolean` | `false` | 色弱模式 |
|
|
256
|
+
|
|
257
|
+
#### 计算属性
|
|
258
|
+
|
|
259
|
+
- `borderRadiusValue` - 圆角值(带单位,如 '6px')
|
|
260
|
+
- `transitionName` - 过渡动画类名
|
|
261
|
+
- `shouldEnableTransition` - 是否应该启用过渡
|
|
262
|
+
- `settingsState` - 完整的设置状态对象
|
|
263
|
+
|
|
264
|
+
### Store 方法
|
|
265
|
+
|
|
266
|
+
#### `syncCSSVariables()`
|
|
267
|
+
|
|
268
|
+
同步所有配置到 CSS 变量(自动调用,通常不需要手动调用)
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
settingsStore.syncCSSVariables();
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
#### `applyPreset(preset: ThemePreset)`
|
|
275
|
+
|
|
276
|
+
应用主题预设方案
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
import { THEME_PRESETS } from "@robot-admin/layout";
|
|
280
|
+
|
|
281
|
+
const techPreset = THEME_PRESETS[0]; // 科技蓝
|
|
282
|
+
settingsStore.applyPreset(techPreset);
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### `resetSettings()`
|
|
286
|
+
|
|
287
|
+
重置所有配置为默认值
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
settingsStore.resetSettings();
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### `updateThemeMode(mode: ThemeMode)`
|
|
294
|
+
|
|
295
|
+
更新主题模式(会触发 onThemeModeChange 回调)
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
settingsStore.updateThemeMode("dark");
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### `exportSettings(): string`
|
|
302
|
+
|
|
303
|
+
导出当前配置为 JSON 字符串
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
const json = settingsStore.exportSettings();
|
|
307
|
+
// 下载或保存...
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
#### `importSettings(json: string): boolean`
|
|
311
|
+
|
|
312
|
+
从 JSON 字符串导入配置
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
try {
|
|
316
|
+
const success = settingsStore.importSettings(jsonString);
|
|
317
|
+
if (success) {
|
|
318
|
+
console.log("配置导入成功");
|
|
319
|
+
}
|
|
320
|
+
} catch (error) {
|
|
321
|
+
console.error("配置格式错误");
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## 📋 常量
|
|
326
|
+
|
|
327
|
+
### `THEME_PRESETS`
|
|
328
|
+
|
|
329
|
+
内置的 6 套主题预设方案:
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
const THEME_PRESETS: ThemePreset[] = [
|
|
333
|
+
{ name: "科技蓝", icon: "💙", primaryColor: "#409eff" },
|
|
334
|
+
{ name: "清新绿", icon: "💚", primaryColor: "#52c41a" },
|
|
335
|
+
{ name: "商务灰", icon: "🖤", primaryColor: "#595959" },
|
|
336
|
+
{ name: "活力橙", icon: "🧡", primaryColor: "#fa8c16" },
|
|
337
|
+
{ name: "优雅紫", icon: "💜", primaryColor: "#722ed1" },
|
|
338
|
+
{ name: "经典红", icon: "❤️", primaryColor: "#f5222d" },
|
|
339
|
+
];
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### `LAYOUT_MODES`
|
|
343
|
+
|
|
344
|
+
6 种布局模式(含 SVG 图标和描述):
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
type LayoutMode =
|
|
348
|
+
| "side"
|
|
349
|
+
| "top"
|
|
350
|
+
| "mix"
|
|
351
|
+
| "mix-top"
|
|
352
|
+
| "reverse-horizontal-mix"
|
|
353
|
+
| "card-layout";
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
- **side** - 左侧菜单布局(经典)
|
|
357
|
+
- **top** - 顶部菜单布局
|
|
358
|
+
- **mix** - 左侧混合菜单布局
|
|
359
|
+
- **mix-top** - 顶部混合菜单布局
|
|
360
|
+
- **reverse-horizontal-mix** - 反转混合布局(开发中)
|
|
361
|
+
- **card-layout** - 卡片布局(开发中)
|
|
362
|
+
|
|
363
|
+
### `COLOR_SWATCHES`
|
|
364
|
+
|
|
365
|
+
颜色选择器的预设色板(8 种常用颜色)
|
|
366
|
+
|
|
367
|
+
### `BORDER_RADIUS_MAP`
|
|
368
|
+
|
|
369
|
+
圆角尺寸映射表:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
{
|
|
373
|
+
small: '4px',
|
|
374
|
+
medium: '6px',
|
|
375
|
+
large: '8px'
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## 🎨 CSS 变量
|
|
380
|
+
|
|
381
|
+
Store 会自动将配置同步到以下 CSS 变量,可直接在样式中使用:
|
|
382
|
+
|
|
383
|
+
```css
|
|
384
|
+
/* 主题色相关 */
|
|
385
|
+
--primary-color: #409eff;
|
|
386
|
+
--primary-color-hover: #66b1ff;
|
|
387
|
+
--primary-color-pressed: #3a8ee6;
|
|
388
|
+
|
|
389
|
+
/* 布局尺寸 */
|
|
390
|
+
--sidebar-width: 220px;
|
|
391
|
+
--sidebar-collapsed-width: 64px;
|
|
392
|
+
--header-height: 56px;
|
|
393
|
+
--tags-view-height: 40px;
|
|
394
|
+
--border-radius: 6px;
|
|
395
|
+
|
|
396
|
+
/* 使用示例 */
|
|
397
|
+
.my-button {
|
|
398
|
+
background: var(--primary-color);
|
|
399
|
+
border-radius: var(--border-radius);
|
|
400
|
+
height: var(--header-height);
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## 📖 类型定义
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
/** 布局模式 */
|
|
408
|
+
type LayoutMode =
|
|
409
|
+
| "side"
|
|
410
|
+
| "top"
|
|
411
|
+
| "mix"
|
|
412
|
+
| "mix-top"
|
|
413
|
+
| "reverse-horizontal-mix"
|
|
414
|
+
| "card-layout";
|
|
415
|
+
|
|
416
|
+
/** 页面动画类型 */
|
|
417
|
+
type TransitionType = "fade" | "slide" | "zoom" | "none";
|
|
418
|
+
|
|
419
|
+
/** 圆角大小 */
|
|
420
|
+
type BorderRadiusSize = "small" | "medium" | "large";
|
|
421
|
+
|
|
422
|
+
/** 标签页风格 */
|
|
423
|
+
type TagsViewStyle = "default" | "card" | "smart";
|
|
424
|
+
|
|
425
|
+
/** 主题模式(继承自 @robot-admin/theme) */
|
|
426
|
+
type ThemeMode = "light" | "dark" | "system";
|
|
427
|
+
|
|
428
|
+
/** 主题预设 */
|
|
429
|
+
interface ThemePreset {
|
|
430
|
+
name: string;
|
|
431
|
+
icon: string;
|
|
432
|
+
primaryColor: string;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/** 设置状态 */
|
|
436
|
+
interface SettingsState {
|
|
437
|
+
// 外观
|
|
438
|
+
themeMode: ThemeMode;
|
|
439
|
+
primaryColor: string;
|
|
440
|
+
borderRadius: BorderRadiusSize;
|
|
441
|
+
transitionType: TransitionType;
|
|
442
|
+
enableTransition: boolean;
|
|
443
|
+
|
|
444
|
+
// 布局
|
|
445
|
+
layoutMode: LayoutMode;
|
|
446
|
+
fixedHeader: boolean;
|
|
447
|
+
showBreadcrumb: boolean;
|
|
448
|
+
showBreadcrumbIcon: boolean;
|
|
449
|
+
showTagsView: boolean;
|
|
450
|
+
tagsViewHeight: number;
|
|
451
|
+
tagsViewStyle: TagsViewStyle;
|
|
452
|
+
showFooter: boolean;
|
|
453
|
+
sidebarWidth: number;
|
|
454
|
+
sidebarCollapsedWidth: number;
|
|
455
|
+
headerHeight: number;
|
|
456
|
+
|
|
457
|
+
// 功能
|
|
458
|
+
enableWatermark: boolean;
|
|
459
|
+
watermarkText: string;
|
|
460
|
+
enableGrayMode: boolean;
|
|
461
|
+
enableColorWeakMode: boolean;
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
## 🔧 完整示例
|
|
466
|
+
|
|
467
|
+
### 基础 Naive UI 项目集成
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
// main.ts
|
|
471
|
+
import { createApp } from "vue";
|
|
472
|
+
import { createPinia } from "pinia";
|
|
473
|
+
import { setupLayout, SettingsDrawer } from "@robot-admin/layout";
|
|
474
|
+
import { useThemeStore } from "@robot-admin/theme";
|
|
475
|
+
import "@robot-admin/layout/style.scss";
|
|
476
|
+
import App from "./App.vue";
|
|
477
|
+
|
|
478
|
+
const app = createApp(App);
|
|
479
|
+
const pinia = createPinia();
|
|
480
|
+
|
|
481
|
+
app.use(pinia);
|
|
482
|
+
|
|
483
|
+
// 初始化主题
|
|
484
|
+
const themeStore = useThemeStore();
|
|
485
|
+
themeStore.init();
|
|
486
|
+
|
|
487
|
+
// 初始化布局(一行搞定)
|
|
488
|
+
setupLayout(app, {
|
|
489
|
+
onThemeModeChange: async (mode) => {
|
|
490
|
+
await themeStore.setMode(mode);
|
|
491
|
+
},
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
app.mount("#app");
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
```vue
|
|
498
|
+
<!-- App.vue -->
|
|
499
|
+
<template>
|
|
500
|
+
<NConfigProvider :theme="naiveTheme">
|
|
501
|
+
<NMessageProvider>
|
|
502
|
+
<div class="app-container">
|
|
503
|
+
<!-- 你的布局和内容 -->
|
|
504
|
+
<router-view />
|
|
505
|
+
|
|
506
|
+
<!-- 设置按钮 -->
|
|
507
|
+
<NButton
|
|
508
|
+
class="settings-trigger"
|
|
509
|
+
circle
|
|
510
|
+
size="large"
|
|
511
|
+
@click="showSettings = true"
|
|
512
|
+
>
|
|
513
|
+
<template #icon>
|
|
514
|
+
<NIcon><Settings /></NIcon>
|
|
515
|
+
</template>
|
|
516
|
+
</NButton>
|
|
517
|
+
|
|
518
|
+
<!-- 设置抽屉(开箱即用)-->
|
|
519
|
+
<SettingsDrawer v-model:show="showSettings" />
|
|
520
|
+
</div>
|
|
521
|
+
</NMessageProvider>
|
|
522
|
+
</NConfigProvider>
|
|
523
|
+
</template>
|
|
524
|
+
|
|
525
|
+
<script setup lang="ts">
|
|
526
|
+
import { ref, computed } from "vue";
|
|
527
|
+
import {
|
|
528
|
+
NConfigProvider,
|
|
529
|
+
NMessageProvider,
|
|
530
|
+
NButton,
|
|
531
|
+
NIcon,
|
|
532
|
+
darkTheme,
|
|
533
|
+
} from "naive-ui";
|
|
534
|
+
import { Settings } from "@vicons/tabler";
|
|
535
|
+
import { SettingsDrawer } from "@robot-admin/layout";
|
|
536
|
+
import { useThemeStore } from "@robot-admin/theme";
|
|
537
|
+
|
|
538
|
+
const themeStore = useThemeStore();
|
|
539
|
+
const showSettings = ref(false);
|
|
540
|
+
|
|
541
|
+
const naiveTheme = computed(() => {
|
|
542
|
+
return themeStore.isDark ? darkTheme : undefined;
|
|
543
|
+
});
|
|
544
|
+
</script>
|
|
545
|
+
|
|
546
|
+
<style>
|
|
547
|
+
.settings-trigger {
|
|
548
|
+
position: fixed;
|
|
549
|
+
right: 20px;
|
|
550
|
+
bottom: 80px;
|
|
551
|
+
z-index: 999;
|
|
552
|
+
}
|
|
553
|
+
</style>
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### 高级:自定义配置
|
|
557
|
+
|
|
558
|
+
```typescript
|
|
559
|
+
// stores/settings.ts
|
|
560
|
+
import { createSettingsStore } from "@robot-admin/layout";
|
|
561
|
+
import { useThemeStore } from "@robot-admin/theme";
|
|
562
|
+
|
|
563
|
+
export const useSettingsStore = createSettingsStore({
|
|
564
|
+
// 自定义默认值
|
|
565
|
+
defaults: {
|
|
566
|
+
layoutMode: "mix",
|
|
567
|
+
primaryColor: "#722ed1",
|
|
568
|
+
showTagsView: false,
|
|
569
|
+
fixedHeader: true,
|
|
570
|
+
enableWatermark: true,
|
|
571
|
+
watermarkText: "My Company",
|
|
572
|
+
},
|
|
573
|
+
|
|
574
|
+
// 自定义存储键名
|
|
575
|
+
storageKey: "my-company-settings",
|
|
576
|
+
|
|
577
|
+
// 主题模式变化回调
|
|
578
|
+
onThemeModeChange: async (mode) => {
|
|
579
|
+
const themeStore = useThemeStore();
|
|
580
|
+
await themeStore.setMode(mode);
|
|
581
|
+
|
|
582
|
+
// 额外逻辑:通知后端
|
|
583
|
+
await fetch("/api/user/theme", {
|
|
584
|
+
method: "PUT",
|
|
585
|
+
body: JSON.stringify({ mode }),
|
|
586
|
+
});
|
|
587
|
+
},
|
|
588
|
+
});
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
## 🎯 最佳实践
|
|
592
|
+
|
|
593
|
+
### 1. 样式使用建议
|
|
594
|
+
|
|
595
|
+
- **推荐使用 SCSS**:可以自定义变量和主题
|
|
596
|
+
- **CSS 变量优先**:使用 `var(--primary-color)` 而非硬编码颜色
|
|
597
|
+
- **响应式设计**:利用 `var(--sidebar-width)` 等布局变量
|
|
598
|
+
|
|
599
|
+
### 2. 性能优化
|
|
600
|
+
|
|
601
|
+
```typescript
|
|
602
|
+
// 懒加载设置抽屉(仅在需要时加载)
|
|
603
|
+
const SettingsDrawer = defineAsyncComponent(() =>
|
|
604
|
+
import("@robot-admin/layout").then((m) => ({ default: m.SettingsDrawer })),
|
|
605
|
+
);
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### 3. 类型安全
|
|
609
|
+
|
|
610
|
+
```typescript
|
|
611
|
+
import type { LayoutMode, SettingsState } from "@robot-admin/layout";
|
|
612
|
+
|
|
613
|
+
// 使用类型约束
|
|
614
|
+
const handleLayoutChange = (mode: LayoutMode) => {
|
|
615
|
+
settingsStore.layoutMode = mode;
|
|
616
|
+
};
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
## 🔗 相关链接
|
|
620
|
+
|
|
621
|
+
- [Robot Admin 完整项目](https://github.com/ChenyCHENYU/Robot_Admin)
|
|
622
|
+
- [@robot-admin/theme](https://www.npmjs.com/package/@robot-admin/theme)
|
|
623
|
+
- [Naive UI 文档](https://www.naiveui.com/)
|
|
624
|
+
|
|
625
|
+
## 📝 更新日志
|
|
626
|
+
|
|
627
|
+
查看 [CHANGELOG.md](./CHANGELOG.md) 了解详细更新记录。
|
|
628
|
+
|
|
629
|
+
## 🤝 贡献
|
|
630
|
+
|
|
631
|
+
欢迎提交 Issue 和 Pull Request!
|
|
632
|
+
|
|
633
|
+
## 📄 License
|
|
634
|
+
|
|
635
|
+
MIT © ChenYu
|