yunzer_go/front/THEME_GUIDE.md

8.9 KiB
Raw Permalink Blame History

主题系统使用指南

概述

项目已成功集成完整的亮色/暗色主题系统,支持一键切换并自动保存用户偏好。

主要特性

  • 完整的亮色和暗色主题定义
  • 自动检测系统主题偏好
  • 用户偏好持久化localStorage
  • 监听系统主题变化
  • 平滑的过渡动画
  • 50+ CSS 变量覆盖所有UI场景
  • TypeScript 类型支持
  • 响应式数据绑定

🚀 快速开始

1. 全局初始化(已完成)

主题系统已在 App.vue 中全局初始化,整个应用自动支持主题切换功能。

2. 主题切换按钮

在头部工具栏可以看到主题切换按钮(🌙/☀️图标),点击即可切换主题。

3. 手动切换主题

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. 在样式文件中使用主题变量

.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. 隐藏滚动条 如需隐藏滚动条但保持滚动功能:

<div class="scrollbar-hide">
  <!-- 内容 -->
</div>

3. 自定义滚动条颜色 如需特定区域使用不同的滚动条颜色,可在组件样式中覆盖:

.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: 基础组件

<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: 按钮组件

<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: 状态提示

<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 类

class ThemeManager {
  // 初始化主题
  init(): void;
  
  // 设置主题
  setTheme(theme: 'light' | 'dark', save?: boolean): void;
  
  // 切换主题
  toggle(): ThemeMode;
  
  // 获取当前主题
  getCurrentTheme(): ThemeMode;
  
  // 检查是否为暗色
  isDark(): boolean;
  
  // 检查是否为亮色
  isLight(): boolean;
}

useTheme Hook

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 - 组件示例