DESIGN_SYSTEM_GUIDE.md 12 KB

设计系统使用指南

📋 概述

本项目采用了全新的设计令牌系统和主题覆盖机制,在保持 Vue 2.6 + Element UI 2.x + 若依框架技术栈不变的前提下,实现了现代化的 UI/UX 升级。

🎨 设计理念

  • 科技蓝主色调:体现专业性和科技感
  • 深色友好:支持明暗主题无缝切换
  • 去线框化:现代化的卡片式设计语言
  • 系统化:基于设计令牌的一致性保障

🏗️ 架构设计

文件结构

src/styles/
├── tokens.scss          # 设计令牌定义(颜色、间距、字体等)
├── overrides-element.scss # Element UI 主题覆盖
├── utilities.scss       # 基础工具类
└── index.scss          # 主样式入口

src/utils/
└── theme.js            # 主题管理工具

src/components/
└── XtThemeToggle.vue   # 主题切换组件

🎯 核心特性

1. 设计令牌系统

基于 CSS 变量实现的设计令牌系统,支持明暗主题切换:

:root {
  /* 主色系 */
  --color-primary: #0EA5E9;
  --color-primary-light: #38BDF8;
  --color-primary-dark: #0284C7;
  
  /* 语义化颜色 */
  --color-success: #22C55E;
  --color-warning: #F59E0B;
  --color-danger: #EF4444;
  
  /* 圆角系统 */
  --radius-lg: 12px;
  --radius-xl: 16px;
  
  /* 阴影系统 */
  --shadow-card: 0 8px 24px rgba(2, 6, 23, 0.06);
  --shadow-card-hover: 0 12px 32px rgba(2, 6, 23, 0.12);
}

/* 暗色主题覆盖 */
html.dark {
  --color-bg-primary: #111827;
  --color-bg-card: #1F2937;
  --color-text-primary: #F9FAFB;
  /* ... */
}

2. Element UI 主题覆盖

完全覆盖 Element UI 的默认样式,使其符合新的设计系统:

  • ✅ 按钮组件:现代化的悬停效果和状态样式
  • ✅ 表单组件:统一的输入框、选择器样式
  • ✅ 数据展示:表格、标签、进度条等组件
  • ✅ 反馈组件:消息提示、通知、工具提示
  • ✅ 导航组件:标签页、分页器样式

3. 工具类系统

提供丰富的 CSS 工具类,支持快速开发:

<!-- 卡片样式 -->
<div class="card">
  <div class="card__header">
    <h3 class="card__header-title">标题</h3>
    <p class="card__header-subtitle">副标题</p>
  </div>
  <div class="card__content">
    内容区域
  </div>
</div>

<!-- 间距工具类 -->
<div class="p-4 m-2 rounded-lg shadow-card">
  <!-- padding: 16px, margin: 8px -->
</div>

<!-- 文本工具类 -->
<p class="text-primary font-semibold text-lg">主要文本</p>
<p class="text-secondary text-sm">次要文本</p>
<p class="muted">弱化文本</p>

<!-- 布局工具类 -->
<div class="flex items-center justify-between">
  <span>左侧内容</span>
  <span>右侧内容</span>
</div>

🔧 使用方法

1. 基础使用

项目已经自动集成了新的设计系统,无需额外配置。所有 Element UI 组件都会自动应用新的主题样式。

2. 主题切换

使用内置的主题切换组件:

<template>
  <div>
    <!-- 按钮模式 -->
    <XtThemeToggle mode="button" :show-text="true" />
    
    <!-- 选择器模式 -->
    <XtThemeToggle mode="select" />
    
    <!-- 分段控制器模式 -->
    <XtThemeToggle mode="segmented" :show-text="true" />
    
    <!-- 开关模式 -->
    <XtThemeToggle mode="switch" :show-label="true" />
  </div>
</template>

<script>
import XtThemeToggle from '@/components/XtThemeToggle'

export default {
  components: {
    XtThemeToggle
  }
}
</script>

3. 程序化主题控制

// 在组件中使用
export default {
  methods: {
    toggleTheme() {
      this.$toggleTheme() // 切换明暗主题
    },
    
    setLightTheme() {
      this.$setTheme('light') // 设置亮色主题
    },
    
    setDarkTheme() {
      this.$setTheme('dark') // 设置暗色主题
    },
    
    setAutoTheme() {
      this.$setTheme('auto') // 跟随系统主题
    },
    
    checkCurrentTheme() {
      console.log('当前主题:', this.$getTheme())
      console.log('是否暗色主题:', this.$isDark())
      console.log('是否亮色主题:', this.$isLight())
    }
  }
}

4. 主题变化监听

import { ThemeMixin } from '@/utils/theme'

export default {
  mixins: [ThemeMixin],
  
  methods: {
    // 主题变化时的自定义处理
    onThemeChange(event) {
      console.log('主题已切换:', event)
      // event.theme - 设置的主题 ('light', 'dark', 'auto')
      // event.effectiveTheme - 实际生效的主题 ('light', 'dark')
      // event.isDark - 是否为暗色主题
      // event.isLight - 是否为亮色主题
      // event.isAuto - 是否为自动主题
      
      // 在这里处理主题变化逻辑
      if (event.isDark) {
        // 暗色主题特殊处理
      } else {
        // 亮色主题特殊处理
      }
    }
  }
}

🎨 设计令牌参考

颜色系统

令牌名称 用途 示例值
--color-primary 主色调 #0EA5E9
--color-success 成功状态 #22C55E
--color-warning 警告状态 #F59E0B
--color-danger 危险状态 #EF4444
--color-text-primary 主要文本 #0F172A / #F9FAFB
--color-text-secondary 次要文本 #475569 / #E5E7EB
--color-bg-card 卡片背景 #FFFFFF / #1F2937
--color-border-primary 主要边框 rgba(2,6,23,0.08) / #374151

间距系统

令牌名称 用途
--spacing-1 4px 最小间距
--spacing-2 8px 小间距
--spacing-3 12px 中小间距
--spacing-4 16px 中等间距
--spacing-6 24px 大间距
--spacing-8 32px 超大间距

圆角系统

令牌名称 用途
--radius-sm 4px 小圆角
--radius-base 6px 基础圆角
--radius-md 8px 中等圆角
--radius-lg 12px 大圆角(默认)
--radius-xl 16px 超大圆角
--radius-full 9999px 完全圆角

阴影系统

令牌名称 用途
--shadow-sm 小阴影
--shadow-base 基础阴影
--shadow-md 中等阴影
--shadow-lg 大阴影
--shadow-xl 超大阴影
--shadow-card 卡片阴影
--shadow-card-hover 卡片悬停阴影

🚀 最佳实践

1. 使用设计令牌

不推荐 - 硬编码颜色值:

.my-component {
  background: #0EA5E9;
  color: #ffffff;
  border-radius: 12px;
}

推荐 - 使用设计令牌:

.my-component {
  background: var(--color-primary);
  color: var(--color-text-inverse);
  border-radius: var(--radius-lg);
}

2. 组件命名规范

所有自定义组件使用 Xt 前缀:

<!-- 正确的组件命名 -->
<XtThemeToggle />
<XtGroupedFormCard />
<XtStickyActionBar />
<XtTestConnectionDrawer />
<XtDiffPublishDialog />
<XtRightSummaryPanel />

3. 样式组织

<template>
  <div class="xt-my-component">
    <div class="component-header">
      <h3 class="header-title">标题</h3>
    </div>
    <div class="component-content">
      内容
    </div>
  </div>
</template>

<style lang="scss" scoped>
.xt-my-component {
  background: var(--color-bg-card);
  border-radius: var(--radius-lg);
  padding: var(--spacing-6);
  box-shadow: var(--shadow-card);
  
  .component-header {
    border-bottom: 1px solid var(--color-border-secondary);
    padding-bottom: var(--spacing-4);
    margin-bottom: var(--spacing-4);
    
    .header-title {
      color: var(--color-text-primary);
      font-size: var(--font-size-lg);
      font-weight: var(--font-weight-semibold);
      margin: 0;
    }
  }
  
  .component-content {
    color: var(--color-text-secondary);
    line-height: var(--line-height-relaxed);
  }
}
</style>

4. 响应式设计

利用内置的响应式工具类:

<div class="card p-4 lg:p-6">
  <h3 class="text-lg lg:text-xl font-semibold">
    响应式标题
  </h3>
  <div class="flex flex-col lg:flex-row gap-4">
    <div class="flex-1">左侧内容</div>
    <div class="flex-1 lg:hidden">移动端显示</div>
    <div class="flex-1 hidden lg:block">桌面端显示</div>
  </div>
</div>

🔍 调试和开发

1. 查看设计令牌

在浏览器开发者工具中查看当前生效的设计令牌:

// 控制台中执行
const style = getComputedStyle(document.documentElement)
console.log('主色调:', style.getPropertyValue('--color-primary'))
console.log('卡片背景:', style.getPropertyValue('--color-bg-card'))
console.log('大圆角:', style.getPropertyValue('--radius-lg'))

2. 动态修改主题色

// 临时修改主色调(用于调试)
document.documentElement.style.setProperty('--color-primary', '#ff6b6b')

// 恢复默认值
document.documentElement.style.removeProperty('--color-primary')

3. 主题切换测试

// 测试所有主题
this.$setTheme('light')
setTimeout(() => this.$setTheme('dark'), 1000)
setTimeout(() => this.$setTheme('auto'), 2000)

📱 可访问性支持

设计系统内置了完善的可访问性支持:

  • 键盘导航:所有交互元素支持键盘操作
  • 焦点管理:清晰的焦点指示器
  • 色彩对比:符合 WCAG 2.1 AA 标准
  • 屏幕阅读器:正确的 ARIA 标签
  • 减少动画:支持 prefers-reduced-motion
  • 高对比度:支持 prefers-contrast: high

🎯 演示页面

访问 /design-system-demo 路由查看完整的设计系统演示,包括:

  • 颜色系统展示
  • 组件样式对比
  • 工具类效果演示
  • 主题切换测试

🐛 问题排查

常见问题

  1. 样式不生效

    • 确认已正确引入 @/styles/index.scss
    • 检查 CSS 变量是否正确定义
    • 确认组件使用了 scoped 样式
  2. 主题切换不工作

    • 确认已安装 ThemePlugin
    • 检查 html 元素是否有 dark
    • 确认 localStorage 权限正常
  3. Element UI 样式覆盖失效

    • 确认样式文件加载顺序正确
    • 检查 CSS 优先级是否足够
    • 使用 !important 强制覆盖(不推荐)

调试工具

// 主题状态检查
console.log('当前主题管理器状态:', {
  theme: this.$theme.getTheme(),
  effectiveTheme: this.$theme.getEffectiveCurrentTheme(),
  isDark: this.$theme.isDark(),
  isLight: this.$theme.isLight(),
  isAuto: this.$theme.isAuto()
})

// CSS 变量检查
const checkTokens = () => {
  const tokens = [
    'color-primary',
    'color-bg-card',
    'radius-lg',
    'shadow-card'
  ]
  
  tokens.forEach(token => {
    const value = getComputedStyle(document.documentElement)
      .getPropertyValue(`--${token}`)
    console.log(`--${token}:`, value)
  })
}
checkTokens()

📚 扩展开发

1. 添加新的设计令牌

src/styles/tokens.scss 中添加:

:root {
  /* 新的颜色令牌 */
  --color-accent: #8B5CF6;
  --color-accent-light: #A78BFA;
  --color-accent-dark: #7C3AED;
  
  /* 新的间距令牌 */
  --spacing-18: 72px;
  --spacing-20: 80px;
}

html.dark {
  /* 暗色主题下的覆盖 */
  --color-accent: #A78BFA;
}

2. 扩展工具类

src/styles/utilities.scss 中添加:

/* 新的工具类 */
.accent {
  color: var(--color-accent) !important;
}

.bg-accent {
  background-color: var(--color-accent) !important;
  color: var(--color-text-inverse) !important;
}

.border-accent {
  border-color: var(--color-accent) !important;
}

3. 自定义主题色

// 动态设置品牌色
this.$theme.setThemeColor('primary', '#your-brand-color')
this.$theme.setThemeColor('primary-light', '#your-light-color')
this.$theme.setThemeColor('primary-dark', '#your-dark-color')

📞 技术支持

如有任何问题或建议,请联系前端架构团队或在项目中创建 Issue。

Happy Coding! 🚀