173 lines
4.0 KiB
Markdown
173 lines
4.0 KiB
Markdown
# 9.14 样式与主题定制
|
||
|
||
:::tip 概述
|
||
前端使用 TailwindCSS + Less 实现样式管理,组件主题通过 NaiveUI 的 `NConfigProvider`(`theme` / `themeOverrides`)实现主题色切换和暗色模式。
|
||
:::
|
||
|
||
## 技术栈
|
||
|
||
| 技术 | 用途 |
|
||
|------|------|
|
||
| TailwindCSS | 原子化 CSS 框架 |
|
||
| Less | 全局样式变量和公共样式 |
|
||
| NaiveUI 主题机制 | NConfigProvider 的 theme / themeOverrides 组件主题覆盖 |
|
||
|
||
## 全局样式文件
|
||
|
||
```text
|
||
ui/src/styles/
|
||
├── index.less # 全局样式入口(@import 子模块)
|
||
├── var.less # Less 变量定义(颜色、尺寸等)
|
||
├── common.less # 公共样式类
|
||
├── tailwind.css # TailwindCSS 入口
|
||
└── transition/ # 过渡动画
|
||
├── index.less
|
||
├── base.less / fade.less / scale.less
|
||
└── slide.less / zoom.less / scroll.less
|
||
```
|
||
|
||
## Less 变量
|
||
|
||
```less
|
||
/* ui/src/styles/var.less */
|
||
@primaryColor: #2d8cf0;
|
||
@primaryColorHover: #57a3f3;
|
||
@header-height: 64px;
|
||
@footer-height: 70px;
|
||
```
|
||
|
||
全局样式入口:
|
||
|
||
```less
|
||
/* ui/src/styles/index.less */
|
||
@import './transition/index.less';
|
||
@import './var.less';
|
||
@import './common.less';
|
||
```
|
||
|
||
## 主题色切换
|
||
|
||
通过 `designSettingStore` 管理主题,`App.vue` 将主题注入 `NConfigProvider`:
|
||
|
||
```typescript
|
||
import { useDesignSettingStore } from '@/store/modules/designSetting';
|
||
|
||
const designStore = useDesignSettingStore();
|
||
|
||
// 切换暗色模式
|
||
designStore.setDarkTheme(true);
|
||
|
||
// 获取当前主题色(可选主题色列表见 designStore.appThemeList)
|
||
const primaryColor = designStore.appTheme;
|
||
```
|
||
|
||
主题色配置来源:
|
||
|
||
```typescript
|
||
// ui/src/settings/designSetting.ts
|
||
export const appThemeList: string[] = ['#2d8cf0', '#0960bd', '#0084f4', /* ... */];
|
||
|
||
const setting = {
|
||
darkTheme: false, // 深色主题开关
|
||
appTheme: '#2d8cf0', // 系统主题色
|
||
appThemeList, // 内置主题色列表
|
||
};
|
||
```
|
||
|
||
## NaiveUI 主题覆盖
|
||
|
||
`App.vue` 根主题注入 `NConfigProvider`,深色模式传 `darkTheme`,主题色通过 `themeOverrides` 覆盖:
|
||
|
||
```vue
|
||
<!-- ui/src/App.vue -->
|
||
<template>
|
||
<NConfigProvider
|
||
:date-locale="dateZhCN"
|
||
:locale="zhCN"
|
||
:theme="getDarkTheme"
|
||
:theme-overrides="getThemeOverrides"
|
||
>
|
||
<!-- 应用内容 -->
|
||
</NConfigProvider>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed } from 'vue';
|
||
import { darkTheme, dateZhCN, zhCN } from 'naive-ui';
|
||
import { useDesignSettingStore } from '@/store/modules/designSetting';
|
||
import { lighten } from '@/utils';
|
||
|
||
const designStore = useDesignSettingStore();
|
||
|
||
// 主题色覆盖(GlobalThemeOverrides)
|
||
const getThemeOverrides = computed(() => {
|
||
const appTheme = designStore.appTheme;
|
||
const lightenStr = lighten(designStore.appTheme, 6);
|
||
return {
|
||
common: {
|
||
primaryColor: appTheme,
|
||
primaryColorSuppl: appTheme,
|
||
primaryColorHover: lightenStr,
|
||
colorLoading: appTheme,
|
||
},
|
||
};
|
||
});
|
||
|
||
// 深色模式:传入 naive-ui 的 darkTheme,否则 undefined(浅色)
|
||
const getDarkTheme = computed(() => (designStore.darkTheme ? darkTheme : undefined));
|
||
</script>
|
||
```
|
||
|
||
:::tip 说明
|
||
NaiveUI 组件样式由 CSS 变量(`--n-*`)驱动,`themeOverrides` 会自动生成对应的 CSS 变量并应用到所有组件。
|
||
:::
|
||
|
||
## TailwindCSS 配置
|
||
|
||
```javascript
|
||
// ui/tailwind.config.js
|
||
module.exports = {
|
||
content: ['./public/**/*.html', './index.html', './src/**/*.{js,jsx,ts,tsx,vue}'],
|
||
important: true,
|
||
theme: {
|
||
extend: {},
|
||
},
|
||
plugins: [],
|
||
};
|
||
```
|
||
|
||
## 自定义全局样式
|
||
|
||
```less
|
||
/* ui/src/styles/common.less */
|
||
|
||
// 页面容器
|
||
.page-container {
|
||
padding: 16px;
|
||
background: var(--bg-color);
|
||
border-radius: 8px;
|
||
}
|
||
|
||
// 搜索表单
|
||
.search-form {
|
||
margin-bottom: 16px;
|
||
padding: 16px;
|
||
background: #fafafa;
|
||
border-radius: 4px;
|
||
}
|
||
```
|
||
|
||
## 局部样式覆盖
|
||
|
||
组件内如需覆盖 NaiveUI 样式,可使用 NaiveUI 提供的 `--n-*` CSS 变量或 TailwindCSS:
|
||
|
||
```vue
|
||
<style scoped>
|
||
/* 覆盖 n-card 内边距 */
|
||
.custom-card {
|
||
--n-padding-top: 8px;
|
||
--n-padding-bottom: 8px;
|
||
}
|
||
</style>
|
||
```
|