4.2 KiB
4.2 KiB
9.14 样式与主题定制
:::tip 概述
前端使用 WindiCSS + Less 实现样式管理,基于 @zougt/vite-plugin-theme-preprocessor 支持主题切换和暗色模式。
:::
技术栈
| 技术 | 用途 |
|---|---|
| WindiCSS | 原子化 CSS 框架(vite-plugin-windicss,兼容 Tailwind 语法) |
| Less | 全局样式变量和主题 |
| Ant Design 主题变量 | 组件样式覆盖(@primary-color 等 Less 变量) |
全局样式文件
ui/src/styles/
├── index.less # 全局样式入口(@import 子模块)
├── color.less # 颜色变量定义(@white、@content-bg、--content-bg 等)
├── common.less # 公共样式类
├── config.less # 配置引用(@import (reference) 'color.less')
├── tailwind.css # Tailwind 兼容指令入口(由 WindiCSS 处理)
├── theme/
│ ├── theme-default.less # 默认主题(引入 Ant Design 默认 Less 主题)
│ └── theme-dark.less # 暗色主题(引入 Ant Design 暗色 Less 主题)
└── transition/
├── index.less # 过渡动画入口
├── base.less / fade.less / scale.less / slide.less / zoom.less / scroll.less
Less 变量
/* ui/src/styles/color.less */
html {
--content-bg: #f0f2f5;
}
@white: #fff;
@content-bg: #f0f2f5;
Ant Design 组件主题通过标准 Less 变量覆盖,例如主色:
/* 覆盖主色示例 */
@primary-color: #165DFF;
主题切换
主题切换基于 @zougt/vite-plugin-theme-preprocessor,两套主题文件在构建时编译为独立作用域样式,运行时通过 toggleTheme 切换:
// build/vite/plugin/theme.ts
import themePreprocessorPlugin from '@zougt/vite-plugin-theme-preprocessor';
export function configThemePlugin(): Plugin[] {
return [
themePreprocessorPlugin({
themeScopes: [
{
scopeName: 'theme-default',
path: path.resolve('src/styles/theme/theme-default.less'),
},
{
scopeName: 'theme-dark',
path: path.resolve('src/styles/theme/theme-dark.less'),
},
],
}),
];
}
页面中通过「项目配置」抽屉切换明暗主题:
// ui/src/layout/components/Header/ProjectSetting.vue
import { toggleTheme } from '@zougt/vite-plugin-theme-preprocessor/dist/browser-utils';
import { useProjectSettingStore } from '@/store/modules/projectSetting';
const settingStore = useProjectSettingStore();
function handleToggleTheme(theme: string) {
const isDark = theme === 'darkness';
settingStore.darkTheme = isDark;
updateDarkTheme(isDark ? 'dark' : 'light');
}
async function updateDarkTheme(mode: 'light' | 'dark') {
toggleTheme({ scopeName: mode === 'dark' ? 'theme-dark' : 'theme-default' });
}
主题状态由 Pinia 的 projectSetting Store 管理(darkTheme、navTheme、headerTheme)。
主题文件
/* ui/src/styles/theme/theme-default.less */
@import "ant-design-vue/lib/style/themes/default.less";
/* ui/src/styles/theme/theme-dark.less */
@import "ant-design-vue/lib/style/themes/dark.less";
自定义组件覆盖直接追加在对应主题文件中,通过生成的作用域类(.theme-default / .theme-dark)区分明暗模式。
WindiCSS 配置
// ui/windi.config.ts
import { defineConfig } from 'vite-plugin-windicss';
export default defineConfig({
darkMode: 'class',
plugins: [createEnterPlugin()],
theme: {
extend: {
zIndex: { '-1': '-1' },
screens: {
sm: '576px',
md: '768px',
lg: '992px',
xl: '1200px',
'2xl': '1600px',
},
},
},
});
:::tip 说明
项目使用 vite-plugin-windicss,类名语法与 TailwindCSS 兼容(class="flex items-center justify-between"),但配置文件是 windi.config.ts 而非 tailwind.config.js。
:::
自定义全局样式
/* ui/src/styles/common.less */
// 页面容器
.page-container {
padding: 16px;
background: var(--content-bg);
border-radius: 8px;
}
// 搜索表单
.search-form {
margin-bottom: 16px;
padding: 16px;
background: #fafafa;
border-radius: 4px;
}