# 9.14 样式与主题定制 :::tip 概述 前端使用 WindiCSS + Less 实现样式管理,通过主题预处理器支持默认/暗色双主题切换。 ::: ## 技术栈 | 技术 | 用途 | |------|------| | WindiCSS | 原子化 CSS 框架(Tailwind 语法兼容) | | Less | 全局样式变量和主题 | | AntDesign Vue 主题变量 | 组件样式覆盖(antd.less 变量) | ## 全局样式文件 ```text ui/src/styles/ ├── index.less # 全局样式入口(@import 过渡动画与公共样式) ├── color.less # 颜色变量定义(内容区背景、基础色) ├── common.less # 公共样式类(页面容器、滚动条、字体) ├── config.less # 配置样式(@import 引用 color.less) ├── tailwind.css # Tailwind/Windi 兼容入口(可选引入) ├── theme/ │ ├── theme-default.less # 默认主题(引入 antd 默认主题变量) │ └── theme-dark.less # 暗色主题(引入 antd 暗色主题变量) └── transition/ # 过渡动画(index/base/fade/scale/scroll/slide/zoom) ``` ## 主题文件 主题文件直接引入 ant-design-vue 官方主题,通过 `@zougt/vite-plugin-theme-preprocessor` 编译为多套作用域变量: ```less /* ui/src/styles/theme/theme-default.less */ @import "ant-design-vue/lib/style/themes/default.less"; ``` ```less /* ui/src/styles/theme/theme-dark.less */ @import "ant-design-vue/lib/style/themes/dark.less"; ``` 构建时的主题作用域配置(`build/vite/plugin/theme.ts`): ```typescript themePreprocessorPlugin({ less: { multipleScopeVars: [ { scopeName: 'theme-default', path: path.resolve('src/styles/theme/theme-default.less') }, { scopeName: 'theme-dark', path: path.resolve('src/styles/theme/theme-dark.less') }, ], extract: false, // 不抽取独立主题 CSS 文件 }, }); ``` :::tip 双主题切换 页面挂载不同的作用域类名(`theme-default` / `theme-dark`)即可整体切换深浅色,所有 antd 组件变量随作用域自动切换。 ::: ## 颜色变量示例 ```less /* ui/src/styles/color.less */ html { //content --content-bg: #f0f2f5; } @white: #fff; @content-bg: #f0f2f5; ``` ## 主题配置管理 布局主题(导航/顶栏配色)通过 `projectSetting` Store 管理: ```typescript import { useProjectSettingStore } from '@/store/modules/projectSetting'; const projectStore = useProjectSettingStore(); // 导航主题 / 顶栏主题 projectStore.navTheme; projectStore.headerTheme; projectStore.setNavTheme('dark'); ``` ## AntDesign 组件覆盖 如需覆盖 antd 组件样式,写在作用域主题文件或 `common.less` 中,使用 `.ant-*` 选择器: ```less /* ui/src/styles/theme/theme-default.less 或页面 scoped 样式 */ .ant-table-thead > tr > th { background: #f5f7fa; } ``` :::warning 覆盖要点 - antd 样式类名为 `.ant-*`(如 `.ant-btn`、`.ant-table`),与 ElementPlus 的 `.el-*` 不同; - 优先调整主题变量(`@primary-color` 等),其次才是选择器覆盖; - 暗色主题的覆盖要放进 `theme-dark.less` 作用域,避免深浅色互相污染。 ::: ## WindiCSS 配置 ```typescript // ui/windi.config.ts import { defineConfig } from 'vite-plugin-windicss'; export default defineConfig({ darkMode: 'class', theme: { extend: { screens: { sm: '576px', md: '768px', lg: '992px', xl: '1200px', '2xl': '1600px', }, }, }, }); ``` ## 自定义全局样式 ```less /* ui/src/styles/common.less */ // 页面容器 #app { width: 100%; height: 100%; } // 滚动条 *::-webkit-scrollbar { width: 12px; height: 12px; } ``` :::tip 样式约定 - 优先使用 WindiCSS 原子类(布局/间距/颜色) - 组件级覆盖写进 `theme/*.less` 作用域,避免散落在页面中 - 与后端联调时注意:列表状态 Tag 颜色应与字典值语义一致(如 1=在用 success / 2=停用 error) :::