frontend_style.md 5.9 KB

1. 样式技术栈与总体方案

该仓库的前端位于 ai-electron/frontend,是一个基于 Vue 3 + TypeScript + Vite 的单页应用。其样式体系由三层组成:

  • 原子类 / 工具类层:使用 UnoCSS(unocss@66.5.10),通过 preset presetWind3(Tailwind CSS v3 兼容)提供响应式、布局、排版等原子类;启用 transformerDirectives 以支持 @apply、@screen 等指令。
  • 组件库层:使用 Ant Design Vue 4.2.6,在业务组件中直接 import Button/Modal/message/theme 等 API,并通过 useDesign hook 获取 antd 的 hashId 和 prefixCls,确保样式隔离。
  • 主题变量层:基于 vite-plugin-theme-vite3 提供的运行时替换能力(replaceStyleVariables、loadDarkThemeCss),实现主色切换、暗色模式、头部/侧栏背景色等主题能力。

图标统一通过 UnoCSS 的 presetIcons 加载,静态引入 @iconify/json 中的 Material Design Icons(i-mdi:*),同时通过 FileSystemIconLoader 从 src/assets/icons 加载本地 SVG 作为自定义 collection。

2. 关键文件

文件 作用
ai-electron/frontend/uno.config.ts UnoCSS 配置:预设、图标白名单(safelist)、SVG 集合、内容扫描范围
ai-electron/frontend/stylelint.config.mjs Stylelint 规则:Less/SCSS/Vue 混合语法校验,禁用部分旧规范,允许 rpx 单位
ai-electron/frontend/src/core/settings/designSetting.ts 设计色板:APP_PRESET_COLOR_LIST、SIDE_BAR_BG_COLOR_LIST、HEADER_PRESET_BG_COLOR_LIST
ai-electron/frontend/src/core/logics/theme/index.ts 主色切换入口 changeTheme(color),调用 replaceStyleVariables 注入 CSS 变量
ai-electron/frontend/src/core/logics/theme/dark.ts 暗色模式切换 updateDarkTheme(mode),通过给 <html> 加 dark class 驱动
ai-electron/frontend/src/core/logics/initAppConfig.ts 应用启动时合并项目配置并初始化主题(主色、暗色、灰度、色弱)
ai-electron/frontend/src/core/hooks/web/useDesign.ts 为组件封装 prefixCls 与 antd hashId 的设计上下文
ai-electron/frontend/package.json 依赖清单,声明 ant-design-vue、unocss、vite-plugin-theme-vite3、less、stylelint-* 等

3. 架构与设计约定

3.1 UnoCSS 原子类为主,Less/SCSS 为辅

  • 组件模板中使用大量 Tailwind 风格的原子类(如 class="sm:text-md absolute left-1/2 ..."),由 UnoCSS 编译期生成对应 CSS。
  • uno.config.ts 的 content.pipeline.include 仅扫描 *.vue / *.tsx / *.ts / *-lib/*.mjs,明确排除 public 目录,避免把第三方静态资源纳入 safelist 计算。
  • 由于菜单图标来自 menu.json 并在运行时拼接 i-<collection>:<name>,无法被静态扫描命中,因此 safelist 中维护了一个很长的白名单(MDI 系列图标)。新增动态图标必须同步添加到 safelist,否则图标不会渲染——这是代码注释中显式说明的约束。

3.2 Ant Design Vue 集成方式

  • 组件按需 import(import { Button, Modal } from 'ant-design-vue'),而非全局注册。
  • 通过 useDesign(scope) hook 统一生成 prefixCls(格式 ${values.prefixCls}-${scope})和 hashId,用于组件内部样式隔离。
  • 业务代码通过 theme.useToken() 读取 antd token,而不是手写颜色值。

3.3 主题系统

  • 默认亮色模式(designSetting.ts 中 darkMode = ThemeEnum.LIGHT),可通过设置面板切换到暗色。
  • 主色切换流程:initAppConfig.ts → changeTheme(color) → generateColors + replaceStyleVariables,将生成的 CSS 变量注入到文档根节点。
  • 暗色模式通过给 <html id="htmlRoot"> 添加/移除 dark class 驱动,生产环境会异步加载暗色主题 CSS(loadDarkThemeCss)。
  • 头部背景色、侧边栏背景色分别通过 updateHeaderBgColor / updateSidebarBgColor 更新,与 designSetting.ts 中的预设色板绑定。

3.4 图标策略

  • 外部图标统一用 MDI(i-mdi:*)和 Simple Line Icons(i-simple-line-icons:*)。
  • 项目自有图标放在 src/assets/icons,通过 FileSystemIconLoader 注册为 svg collection,使用时以 i:svg:<name> 引用。

4. 约定与约束

  • 样式语言:项目同时存在 Less 与 SCSS(stylelint.config.mjs 对两者分别启用 postcss-less 与 postcss-scss),但 UnoCSS 是主要的原子类引擎;所有 .vue / .less / .scss / .css 均受 stylelint 校验。
  • 禁止的 CSS 属性:stylelint 规则 declaration-property-value-disallowed-list.inset 禁止所有 inset 简写属性,强制使用 top/right/bottom/left 四个方向属性(declaration-property-value-allowed-list 显式允许这四个属性)。
  • 伪类/伪元素扩展名:允许 Vue 深度选择器 ::v-deep、::v-global、::v-slotted 以及 :global、:deep,以便穿透 antd 组件样式。
  • 未知 at-rule 白名单:stylelint 允许 UnoCSS 与 Less/SCSS 特有的 at-rule(extends、ignores、include、mixin、if、else、media、for、at-root、unocss、apply、variants、responsive、screen、function、each、use、forward、return),避免 UnoCSS 指令触发 lint 错误。
  • rpx 单位允许:unit-no-unknown 规则放行 rpx,适配移动端或桌面端缩放场景。
  • 图标白名单维护义务:uno.config.ts 的 safelist 是所有“运行时拼接图标”的唯一来源;新增动态图标名若未加入 safelist,构建产物中将缺失该图标。
  • 主题色来源单一:除 antd token 外,所有业务色值应来自 designSetting.ts 的预设列表或通过 changeTheme 动态生成,不应硬编码十六进制颜色。
  • Node 版本要求:package.json 的 engines.node 限定 >=20.19 || >=22.12,样式工具链(Vite 7、ESLint 9、TypeScript 5、UnoCSS 66)都依赖较新的 Node 环境。