415 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			415 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # 主题系统使用指南
 | ||
| 
 | ||
| ## 概述
 | ||
| 
 | ||
| 项目已成功集成完整的亮色/暗色主题系统,支持一键切换并自动保存用户偏好。
 | ||
| 
 | ||
| ## ✨ 主要特性
 | ||
| 
 | ||
| - ✅ 完整的亮色和暗色主题定义
 | ||
| - ✅ 自动检测系统主题偏好
 | ||
| - ✅ 用户偏好持久化(localStorage)
 | ||
| - ✅ 监听系统主题变化
 | ||
| - ✅ 平滑的过渡动画
 | ||
| - ✅ 50+ CSS 变量覆盖所有UI场景
 | ||
| - ✅ TypeScript 类型支持
 | ||
| - ✅ 响应式数据绑定
 | ||
| 
 | ||
| ## 🚀 快速开始
 | ||
| 
 | ||
| ### 1. 全局初始化(已完成)
 | ||
| 
 | ||
| 主题系统已在 `App.vue` 中全局初始化,整个应用自动支持主题切换功能。
 | ||
| 
 | ||
| ### 2. 主题切换按钮
 | ||
| 
 | ||
| 在头部工具栏可以看到主题切换按钮(🌙/☀️图标),点击即可切换主题。
 | ||
| 
 | ||
| ### 3. 手动切换主题
 | ||
| 
 | ||
| ```typescript
 | ||
| import { useTheme } from '@/utils/theme';
 | ||
| 
 | ||
| // 在组件中使用
 | ||
| const { toggle, setTheme, currentTheme, isDark } = useTheme();
 | ||
| 
 | ||
| // 切换主题
 | ||
| toggle();
 | ||
| 
 | ||
| // 设置为特定主题
 | ||
| setTheme('dark'); // 或 'light'
 | ||
| 
 | ||
| // 获取当前主题状态
 | ||
| console.log(isDark()); // true 或 false
 | ||
| console.log(currentTheme); // 'light' 或 'dark'
 | ||
| ```
 | ||
| 
 | ||
| ### 4. 在样式文件中使用主题变量
 | ||
| 
 | ||
| ```scss
 | ||
| .my-component {
 | ||
|   background: var(--background-color);
 | ||
|   color: var(--text-color);
 | ||
|   border: 1px solid var(--border-color);
 | ||
|   
 | ||
|   &:hover {
 | ||
|     background: var(--background-hover);
 | ||
|     border-color: var(--border-color-hover);
 | ||
|   }
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ## 📋 可用的 CSS 变量
 | ||
| 
 | ||
| ### 主题标识
 | ||
| - `--theme-mode`: 当前主题模式 ('light' 或 'dark')
 | ||
| 
 | ||
| ### 主要颜色
 | ||
| - `--primary-color`, `--primary-hover`, `--primary-active`
 | ||
| - `--secondary-color`, `--secondary-hover`, `--secondary-active`
 | ||
| - `--accent-color`, `--accent-hover`
 | ||
| 
 | ||
| ### 背景颜色
 | ||
| - `--background-color`: 主要背景
 | ||
| - `--background-secondary`, `--background-tertiary`
 | ||
| - `--background-hover`
 | ||
| 
 | ||
| ### 文本颜色
 | ||
| - `--text-color`: 主要文本
 | ||
| - `--text-secondary`, `--text-tertiary`
 | ||
| - `--text-inverse`: 反转文本色
 | ||
| 
 | ||
| ### 边框颜色
 | ||
| - `--border-color`, `--border-color-hover`, `--border-color-active`
 | ||
| 
 | ||
| ### 状态颜色
 | ||
| - `--success-color`, `--success-bg`
 | ||
| - `--warning-color`, `--warning-bg`
 | ||
| - `--error-color`, `--error-bg`
 | ||
| - `--info-color`, `--info-bg`
 | ||
| 
 | ||
| ### 组件颜色
 | ||
| - `--card-bg`, `--card-shadow`
 | ||
| - `--sidebar-bg`, `--sidebar-hover`
 | ||
| - `--header-bg`
 | ||
| 
 | ||
| ### 阴影
 | ||
| - `--shadow-sm`, `--shadow-md`, `--shadow-lg`, `--shadow-xl`
 | ||
| 
 | ||
| ### 圆角
 | ||
| - `--border-radius`, `--border-radius-sm`
 | ||
| - `--border-radius-lg`, `--border-radius-xl`
 | ||
| - `--border-radius-full`
 | ||
| 
 | ||
| ### 过渡
 | ||
| - `--transition-base`: all 0.3s
 | ||
| - `--transition-fast`: all 0.15s
 | ||
| - `--transition-slow`: all 0.5s
 | ||
| 
 | ||
| ### 字体
 | ||
| - `--font-family-base`
 | ||
| 
 | ||
| ## 🎨 自定义滚动条
 | ||
| 
 | ||
| 项目已经内置了自定义滚动条样式,支持主题切换:
 | ||
| 
 | ||
| ### 特性
 | ||
| - ✅ 自动适配亮色/暗色主题
 | ||
| - ✅ 支持 WebKit 和 Firefox 浏览器
 | ||
| - ✅ 平滑的过渡动画
 | ||
| - ✅ 悬停效果增强
 | ||
| - ✅ 支持隐藏滚动条(保持滚动功能)
 | ||
| 
 | ||
| ### 滚动条大小
 | ||
| - 宽度/高度:8px
 | ||
| - 适合现代 UI 风格
 | ||
| - 不影响内容布局
 | ||
| 
 | ||
| ### 使用方式
 | ||
| 
 | ||
| **1. 默认滚动条(自动应用)**
 | ||
| 所有滚动容器都会自动使用主题滚动条样式。
 | ||
| 
 | ||
| **2. 隐藏滚动条**
 | ||
| 如需隐藏滚动条但保持滚动功能:
 | ||
| 
 | ||
| ```vue
 | ||
| <div class="scrollbar-hide">
 | ||
|   <!-- 内容 -->
 | ||
| </div>
 | ||
| ```
 | ||
| 
 | ||
| **3. 自定义滚动条颜色**
 | ||
| 如需特定区域使用不同的滚动条颜色,可在组件样式中覆盖:
 | ||
| 
 | ||
| ```scss
 | ||
| .my-custom-scroll {
 | ||
|   &::-webkit-scrollbar-thumb {
 | ||
|     background: var(--primary-color);
 | ||
|   }
 | ||
|   
 | ||
|   scrollbar-color: var(--primary-color) var(--background-secondary);
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### 浏览器兼容性
 | ||
| - ✅ Chrome/Edge: 完美支持
 | ||
| - ✅ Firefox: 完美支持
 | ||
| - ✅ Safari: 完美支持
 | ||
| - ✅ Opera: 完美支持
 | ||
| - ⚠️ IE: 使用原生滚动条
 | ||
| 
 | ||
| ## 📁 文件结构
 | ||
| 
 | ||
| ```
 | ||
| front/
 | ||
| ├── src/
 | ||
| │   ├── App.vue                    # 全局初始化主题系统 ⭐
 | ||
| │   ├── main.ts                    # 入口文件,引入样式
 | ||
| │   ├── assets/
 | ||
| │   │   └── css/
 | ||
| │   │       ├── root.scss           # 主题变量定义
 | ||
| │   │       └── theme-usage.md     # 详细使用文档
 | ||
| │   ├── utils/
 | ||
| │   │   └── theme.ts               # 主题切换工具
 | ||
| │   ├── components/
 | ||
| │   │   └── ThemeToggle.vue        # 主题切换组件
 | ||
| │   └── views/
 | ||
| │       └── components/
 | ||
| │           └── layout.vue         # 已集成主题切换按钮
 | ||
| ├── THEME_GUIDE.md                 # 本文件
 | ||
| ```
 | ||
| 
 | ||
| ## 💡 使用示例
 | ||
| 
 | ||
| ### 示例 1: 基础组件
 | ||
| 
 | ||
| ```vue
 | ||
| <template>
 | ||
|   <div class="card">
 | ||
|     <h3>{{ title }}</h3>
 | ||
|     <p>{{ content }}</p>
 | ||
|   </div>
 | ||
| </template>
 | ||
| 
 | ||
| <script setup lang="ts">
 | ||
| defineProps<{
 | ||
|   title: string;
 | ||
|   content: string;
 | ||
| }>();
 | ||
| </script>
 | ||
| 
 | ||
| <style scoped>
 | ||
| .card {
 | ||
|   background: var(--card-bg);
 | ||
|   color: var(--text-color);
 | ||
|   padding: 20px;
 | ||
|   border: 1px solid var(--border-color);
 | ||
|   border-radius: var(--border-radius-lg);
 | ||
|   box-shadow: var(--card-shadow);
 | ||
|   transition: var(--transition-base);
 | ||
| }
 | ||
| 
 | ||
| .card:hover {
 | ||
|   box-shadow: var(--shadow-lg);
 | ||
|   border-color: var(--border-color-hover);
 | ||
| }
 | ||
| </style>
 | ||
| ```
 | ||
| 
 | ||
| ### 示例 2: 按钮组件
 | ||
| 
 | ||
| ```vue
 | ||
| <template>
 | ||
|   <button :class="buttonClass">
 | ||
|     {{ text }}
 | ||
|   </button>
 | ||
| </template>
 | ||
| 
 | ||
| <script setup lang="ts">
 | ||
| defineProps<{
 | ||
|   type?: 'primary' | 'secondary' | 'danger';
 | ||
|   text: string;
 | ||
| }>();
 | ||
| 
 | ||
| const buttonClass = computed(() => ({
 | ||
|   'btn-primary': true,
 | ||
|   [`btn-${props.type || 'primary'}`]: true,
 | ||
| }));
 | ||
| </script>
 | ||
| 
 | ||
| <style scoped>
 | ||
| button {
 | ||
|   padding: 8px 16px;
 | ||
|   border-radius: var(--border-radius);
 | ||
|   border: none;
 | ||
|   cursor: pointer;
 | ||
|   transition: var(--transition-fast);
 | ||
|   font-weight: 500;
 | ||
| }
 | ||
| 
 | ||
| .btn-primary {
 | ||
|   background: var(--primary-color);
 | ||
|   color: var(--text-inverse);
 | ||
| }
 | ||
| 
 | ||
| .btn-primary:hover {
 | ||
|   background: var(--primary-hover);
 | ||
| }
 | ||
| 
 | ||
| .btn-secondary {
 | ||
|   background: var(--secondary-color);
 | ||
|   color: var(--text-inverse);
 | ||
| }
 | ||
| 
 | ||
| .btn-danger {
 | ||
|   background: var(--error-color);
 | ||
|   color: var(--text-inverse);
 | ||
| }
 | ||
| </style>
 | ||
| ```
 | ||
| 
 | ||
| ### 示例 3: 状态提示
 | ||
| 
 | ||
| ```vue
 | ||
| <template>
 | ||
|   <div :class="['alert', `alert-${type}`]">
 | ||
|     <i :class="iconClass"></i>
 | ||
|     <span>{{ message }}</span>
 | ||
|   </div>
 | ||
| </template>
 | ||
| 
 | ||
| <script setup lang="ts">
 | ||
| const props = defineProps<{
 | ||
|   type: 'success' | 'warning' | 'error' | 'info';
 | ||
|   message: string;
 | ||
| }>();
 | ||
| 
 | ||
| const iconClass = computed(() => {
 | ||
|   const icons = {
 | ||
|     success: 'fa-check-circle',
 | ||
|     warning: 'fa-exclamation-triangle',
 | ||
|     error: 'fa-times-circle',
 | ||
|     info: 'fa-info-circle',
 | ||
|   };
 | ||
|   return `fas ${icons[props.type]}`;
 | ||
| });
 | ||
| </script>
 | ||
| 
 | ||
| <style scoped>
 | ||
| .alert {
 | ||
|   padding: 12px 16px;
 | ||
|   border-radius: var(--border-radius);
 | ||
|   display: flex;
 | ||
|   align-items: center;
 | ||
|   gap: 8px;
 | ||
| }
 | ||
| 
 | ||
| .alert-success {
 | ||
|   color: var(--success-color);
 | ||
|   background: var(--success-bg);
 | ||
| }
 | ||
| 
 | ||
| .alert-warning {
 | ||
|   color: var(--warning-color);
 | ||
|   background: var(--warning-bg);
 | ||
| }
 | ||
| 
 | ||
| .alert-error {
 | ||
|   color: var(--error-color);
 | ||
|   background: var(--error-bg);
 | ||
| }
 | ||
| 
 | ||
| .alert-info {
 | ||
|   color: var(--info-color);
 | ||
|   background: var(--info-bg);
 | ||
| }
 | ||
| </style>
 | ||
| ```
 | ||
| 
 | ||
| ## 🔧 API 参考
 | ||
| 
 | ||
| ### ThemeManager 类
 | ||
| 
 | ||
| ```typescript
 | ||
| class ThemeManager {
 | ||
|   // 初始化主题
 | ||
|   init(): void;
 | ||
|   
 | ||
|   // 设置主题
 | ||
|   setTheme(theme: 'light' | 'dark', save?: boolean): void;
 | ||
|   
 | ||
|   // 切换主题
 | ||
|   toggle(): ThemeMode;
 | ||
|   
 | ||
|   // 获取当前主题
 | ||
|   getCurrentTheme(): ThemeMode;
 | ||
|   
 | ||
|   // 检查是否为暗色
 | ||
|   isDark(): boolean;
 | ||
|   
 | ||
|   // 检查是否为亮色
 | ||
|   isLight(): boolean;
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### useTheme Hook
 | ||
| 
 | ||
| ```typescript
 | ||
| export const useTheme = () => {
 | ||
|   return {
 | ||
|     currentTheme: ThemeMode;  // 当前主题
 | ||
|     toggle(): void;           // 切换主题
 | ||
|     setTheme(theme: ThemeMode): void;  // 设置主题
 | ||
|     isDark(): boolean;        // 是否暗色
 | ||
|     isLight(): boolean;       // 是否亮色
 | ||
|   };
 | ||
| };
 | ||
| ```
 | ||
| 
 | ||
| ## 🎨 主题配色方案
 | ||
| 
 | ||
| ### 亮色主题
 | ||
| - 背景: 白色 → 浅灰
 | ||
| - 文本: 深灰 → 黑色
 | ||
| - 主色: 蓝色系 (#3498db)
 | ||
| - 次色: 绿色系 (#2ecc71)
 | ||
| - 强调: 黄色系 (#ffcc00)
 | ||
| 
 | ||
| ### 暗色主题
 | ||
| - 背景: 深灰 → 黑色
 | ||
| - 文本: 浅灰 → 白色
 | ||
| - 主色: 浅蓝系 (#5dade2)
 | ||
| - 次色: 浅绿系 (#58d68d)
 | ||
| - 强调: 浅黄系 (#f7dc6f)
 | ||
| 
 | ||
| ## 📝 注意事项
 | ||
| 
 | ||
| 1. **始终使用 CSS 变量**: 不要在样式中硬编码颜色值
 | ||
| 2. **响应式绑定**: 在 Vue 组件中使用 `computed` 来响应式获取主题
 | ||
| 3. **测试两个主题**: 确保在亮色和暗色主题下都有良好的可读性
 | ||
| 4. **避免高对比度**: 暗色主题使用柔和的色彩,减少眼部疲劳
 | ||
| 5. **合理使用阴影**: 暗色主题中使用更深的阴影增强层次感
 | ||
| 
 | ||
| ## 🐛 故障排除
 | ||
| 
 | ||
| ### 主题切换不生效
 | ||
| - 确保在组件中正确导入并使用 `useTheme()`
 | ||
| - 检查是否正确添加了 `root.scss` 到主样式文件
 | ||
| 
 | ||
| ### 样式未应用
 | ||
| - 确保使用 CSS 变量而不是硬编码值
 | ||
| - 检查元素是否正确继承了主题变量
 | ||
| 
 | ||
| ### TypeScript 错误
 | ||
| - 确保已正确导入类型定义
 | ||
| - 重启 VS Code 的 TypeScript 服务器
 | ||
| 
 | ||
| ## 📞 支持
 | ||
| 
 | ||
| 如有问题或建议,请查看:
 | ||
| - `front/src/assets/css/theme-usage.md` - 详细使用文档
 | ||
| - `front/src/utils/theme.ts` - 源代码和注释
 | ||
| - `front/src/components/ThemeToggle.vue` - 组件示例
 | ||
| 
 |