# @g3soft/framework G3Soft 前端框架。目标:**基础架子一处维护,留好插槽和接口,业务项目引用方便,既不绑死又灵活。** ## 设计原则 > framework 提供「骨架 + 契约」,业务负责「填充」;依赖单向 `host → framework`,framework 永不 import 业务代码。 - **三层契约**:配置契约(`G3FrameworkOptions`)/ 数据契约(`NavItem`、`G3RouteMeta`、`UserInfo`)/ UI 契约(slots + emits)。 - **一切外部信息靠注入**:菜单、用户、token、跳转都由宿主提供,framework 内部零业务依赖。 - **默认能跑**:零配置即可启动(默认 `sidebar-nav` + 浅色),配置与插槽均为可选增强。 ## 归属边界 | 层 | 内容 | 说明 | |---|---|---| | `core` | 布局(7 种模式)、偏好模型、契约类型 | 后端无关,只依赖 `vue`(peer) + `@g3soft/ui` | | `presets/*` | 传输、`ApiResponse` 解包、`/data/*` client、默认菜单源 | **后续接入**,可选,import 才生效 | | 项目 | 业务接口、业务页面 | —— | **铁律**:`core` 里绝不出现具体后端名(如 `s_menu`、`/data/loaddata`、`ApiResponse`);一旦出现,它就该在 `presets`。 ## 当前进度 - [x] core 类型契约(数据 / 配置 / UI 三类) - [x] 偏好层:`defaultPreferences` / `usePreferences`(reactive 单例,无需 pinia)/ 持久化 / `applyThemeVars` - [x] `createG3Framework`(`app.use()` 一次初始化) - [x] 布局子组件:Logo / 递归 Menu(垂直+水平)/ Sidebar(单列+双列,含折叠按钮、拖拽调宽、悬浮展开)/ Header / Breadcrumb / Tabbar - [x] `G3Layout` 编排 7 种模式(模式配置表驱动) - [ ] 偏好抽屉面板 - [ ] 接线层 `G3AdminLayout`(接 router / 页签状态 / 用户菜单) - [ ] 接口层 preset(`/request` + g3-backend + 默认菜单源) 布局结构与交互对齐 [vben-admin](https://github.com/vbenjs/vue-vben-admin) 的 `layout-ui`,样式改写为 `--g3-*` 变量 + `g3-` 前缀(**不引入 Tailwind**,业务项目零额外配置)。 ## 使用 ```ts // main.ts —— 初始化(可选) import { createG3Framework } from '@g3soft/framework' app.use( createG3Framework({ preferences: { app: { layout: 'sidebar-nav' }, theme: { colorPrimary: '#2563eb' } }, storageKey: 'g3-preferences', }), ) ``` ```vue ``` 菜单数据由宿主注入(`:menus` 直接给数组,或 `:menu-source` 给函数),framework 不关心来源。 ## 偏好与主题 - `usePreferences()`:读偏好(只读响应式)、`update(patch)` / `setLayout()` / `toggleSidebar()`。 - 偏好状态是**模块级 reactive 单例**,不依赖 pinia;持久化用 `localStorage`(SSR 安全)。 - 主题唯一输出仍是 `@g3soft/ui` 的 `ConfigProvider → derivePalette → --g3-*`;`radius` / `fontSize` / 布局尺寸写入 CSS 变量。 ## 归属边界 | 层 | 内容 | 说明 | |---|---|---| | `core` | 布局(7 种模式)、偏好、契约类型 | 后端无关,只依赖 `vue`(peer) + `@g3soft/ui` | | `presets/*` | 传输、`ApiResponse` 解包、`/data/*` client、默认菜单源 | **后续接入**,可选,import 才生效 | | 项目 | 业务接口、业务页面 | —— | **铁律**:`core` 里绝不出现具体后端名(如 `s_menu`、`/data/loaddata`、`ApiResponse`);一旦出现,它就该在 `presets`。