设计系统
🎨 设计理念
现代简约的设计理念,注重用户体验和数据可视化,为家庭财务管理提供直观、高效的界面设计。
🌈 色彩系统
主色系 - 金黄色 #ffda44
/* 主品牌色 - 金黄色 */
--primary-color: #ffda44;
--primary-50: #fffdf0;
--primary-100: #fff8d6;
--primary-200: #fff0ad;
--primary-300: #ffe584;
--primary-400: #ffda44; /* 主色 */
--primary-500: #ffd700;
--primary-600: #e6c200;
--primary-700: #ccad00;
--primary-800: #b39900;
--primary-900: #998000;
/* 渐变色 */
--primary-gradient: linear-gradient(135deg, #ffda44 0%, #ffd700 100%);
--primary-gradient-dark: linear-gradient(135deg, #e6c200 0%, #ccad00 100%);功能色系
/* 页面主题色 */
--dashboard-blue: #3b82f6; /* 首页 - 仪表盘 */
--transaction-green: #10b981; /* 交易记录 - 交易 */
--wallet-purple: #8b5cf6; /* 资产管理 - 钱包 */
--budget-blue: #3b82f6; /* 预算管理 - 资金 */
--subscription-orange: #f59e0b; /* 订阅管理 - 日历 */
--category-cyan: #06b6d4; /* 分类管理 - 标签 */
/* 语义色 */
--success: #10b981; /* 成功/收入 */
--warning: #f59e0b; /* 警告 */
--error: #ef4444; /* 错误/支出 */
--info: #3b82f6; /* 信息 */
--neutral: #6b7280; /* 中性 */中性色系
/* 灰色调 */
--gray-50: #f9fafb;
--gray-100: #f3f4f6;
--gray-200: #e5e7eb;
--gray-300: #d1d5db;
--gray-400: #9ca3af;
--gray-500: #6b7280;
--gray-600: #4b5563;
--gray-700: #374151;
--gray-800: #1f2937;
--gray-900: #111827;深色模式
/* 深色背景 */
--dark-bg-primary: #0f172a;
--dark-bg-secondary: #1e293b;
--dark-bg-tertiary: #334155;
/* 深色文本 */
--dark-text-primary: #f8fafc;
--dark-text-secondary: #cbd5e1;
--dark-text-tertiary: #94a3b8;📐 布局规范
页面结构模板
<template>
<div class="page-container min-h-screen bg-gray-50/50 dark:bg-gray-900/50">
<!-- 1. 粘性页头 -->
<div class="page-header sticky top-0 z-10 backdrop-blur-sm bg-white/90 dark:bg-gray-800/90 border-b border-gray-200/50 dark:border-gray-700/50 px-6 py-4 mb-6 shadow-sm">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-lg bg-gradient-to-br from-{color}-500 to-{color}-600 dark:from-{color}-600 dark:to-{color}-700 shadow-md">
<span class="i-{icon} text-white text-xl" />
</div>
<div>
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100">页面标题</h2>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">页面副标题</p>
</div>
</div>
<a-button type="primary" size="small" class="!rounded-lg !px-4">
<span class="i-ant-design-plus-outlined mr-1" />
主要操作
</a-button>
</div>
</div>
<!-- 2. 页面内容 -->
<div class="page-content px-4 md:px-6 pb-6 space-y-6">
<!-- 内容区域 -->
</div>
</div>
</template>网格系统
/* 统计卡片布局 */
.stats-grid {
@apply grid gap-3;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
/* 响应式列数 */
.responsive-grid {
@apply grid gap-3;
grid-template-columns: repeat(1, 1fr); /* 默认 1 列 */
@media (min-width: 640px) {
grid-template-columns: repeat(2, 1fr); /* sm: 2 列 */
}
@media (min-width: 768px) {
grid-template-columns: repeat(3, 1fr); /* md: 3 列 */
}
@media (min-width: 1024px) {
grid-template-columns: repeat(4, 1fr); /* lg: 4 列 */
}
}🧩 组件规范
统计卡片 (StatCard)
<template>
<div class="stat-card bg-white dark:bg-gray-800 rounded-xl p-3 shadow-sm border border-gray-100 dark:border-gray-700/50 transition-all duration-300 hover:shadow-md">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center gap-2">
<div class="w-8 h-8 rounded-lg bg-gradient-to-br from-{color}-500 to-{color}-600 flex items-center justify-center">
<span class="i-{icon} text-white text-base" />
</div>
<div class="min-w-0 flex-1">
<h3 class="text-sm font-semibold text-gray-800 dark:text-gray-200 truncate">{{ title }}</h3>
<p class="text-[10px] text-gray-500 dark:text-gray-400 truncate leading-tight">{{ subtitle }}</p>
</div>
</div>
</div>
<div class="text-right">
<div class="text-lg font-bold text-gray-900 dark:text-gray-100 whitespace-nowrap">
{{ prefix }}{{ formatValue(value) }}
</div>
<div class="text-[10px] text-gray-500 dark:text-gray-400 whitespace-nowrap">
{{ footnote }}
</div>
</div>
</div>
</template>表格组件
<template>
<div class="table-container bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-100 dark:border-gray-700/50 overflow-hidden">
<div class="p-5">
<a-table
:columns="columns"
:data-source="data"
size="small"
class="custom-table"
:pagination="{ pageSize: 10 }"
>
<!-- 表格内容 -->
</a-table>
</div>
</div>
</template>
<style scoped>
.custom-table {
:deep(.ant-table) {
@apply rounded-xl overflow-hidden;
}
:deep(.ant-table-thead > tr > th) {
@apply bg-gradient-to-b from-gray-50 to-gray-100/50 dark:from-gray-700 dark:to-gray-700/50 text-gray-700 dark:text-gray-300 font-semibold border-b-2 border-gray-200 dark:border-gray-600 !text-xs !py-2;
}
:deep(.ant-table-tbody > tr) {
@apply transition-colors duration-200;
}
:deep(.ant-table-tbody > tr:hover) {
@apply bg-blue-50/50 dark:bg-gray-700/30;
}
:deep(.ant-table-tbody > tr > td) {
@apply border-b border-gray-100 dark:border-gray-700/50 !py-2 !text-xs;
}
}
</style>筛选表单
<template>
<div class="filter-container bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-100 dark:border-gray-700/50 overflow-hidden">
<div class="p-4">
<a-form :model="filters" class="filter-form">
<a-row :gutter="[12, 12]">
<a-col :xs="12" :sm="6" :md="6" :lg="6">
<a-form-item label="筛选条件" class="!mb-3">
<a-select
v-model:value="filters.field"
placeholder="请选择"
size="small"
class="w-full !rounded-lg"
allow-clear
>
<a-select-option value="option1">选项1</a-select-option>
<a-select-option value="option2">选项2</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :span="24" class="text-right">
<a-space>
<a-button type="primary" size="small" class="!rounded-lg !px-4">
<span class="i-ant-design-search-outlined mr-1" />
搜索
</a-button>
<a-button size="small" class="!rounded-lg !px-4">
<span class="i-ant-design-reload-outlined mr-1" />
重置
</a-button>
</a-space>
</a-col>
</a-row>
</a-form>
</div>
</div>
</template>📝 字体规范
字体大小层级
/* 页面标题 */
.text-page-title {
@apply text-2xl font-bold text-gray-800 dark:text-gray-100;
}
/* 卡片标题 */
.text-card-title {
@apply text-sm font-semibold text-gray-800 dark:text-gray-200;
}
/* 表格标题 */
.text-table-title {
@apply text-xs font-semibold text-gray-700 dark:text-gray-300;
}
/* 正文内容 */
.text-body {
@apply text-xs text-gray-600 dark:text-gray-300;
}
/* 辅助文字 */
.text-caption {
@apply text-[10px] text-gray-500 dark:text-gray-400;
}
/* 数值显示 */
.text-value {
@apply text-sm font-bold text-gray-900 dark:text-gray-100;
}
/* 小数值 */
.text-value-small {
@apply text-xs font-semibold text-gray-800 dark:text-gray-200;
}文本处理
/* 不换行 */
.text-nowrap {
@apply whitespace-nowrap;
}
/* 截断 */
.text-truncate {
@apply truncate;
}
/* 多行截断 */
.text-clamp-2 {
@apply overflow-hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}📏 间距系统
基础间距
/* 内边距 */
.p-xs { @apply p-1; } /* 4px */
.p-sm { @apply p-2; } /* 8px */
.p-md { @apply p-3; } /* 12px */
.p-lg { @apply p-4; } /* 16px */
.p-xl { @apply p-5; } /* 20px */
.p-2xl { @apply p-6; } /* 24px */
/* 外边距 */
.m-xs { @apply m-1; } /* 4px */
.m-sm { @apply m-2; } /* 8px */
.m-md { @apply m-3; } /* 12px */
.m-lg { @apply m-4; } /* 16px */
.m-xl { @apply m-5; } /* 20px */
.m-2xl { @apply m-6; } /* 24px */
/* 间距 */
.gap-xs { @apply gap-1; } /* 4px */
.gap-sm { @apply gap-2; } /* 8px */
.gap-md { @apply gap-3; } /* 12px */
.gap-lg { @apply gap-4; } /* 16px */
.gap-xl { @apply gap-5; } /* 20px */组件间距
/* 页面级间距 */
.page-spacing {
@apply px-4 md:px-6 pb-6 space-y-6;
}
/* 卡片间距 */
.card-spacing {
@apply p-3 md:p-4 lg:p-5;
}
/* 表格间距 */
.table-spacing {
@apply p-4 md:p-5;
}
/* 表单间距 */
.form-spacing {
@apply p-4;
}
/* 网格间距 */
.grid-spacing {
@apply gap-3;
}✨ 动画效果
页面动画
/* 页头下滑 */
.page-header {
animation: slideDown 0.3s ease-out;
}
@keyframes slideDown {
from {
transform: translateY(-10px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
/* 内容淡入 */
.page-content {
animation: fadeInUp 0.4s ease-out;
}
@keyframes fadeInUp {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}交互动画
/* 按钮悬停 */
.btn-hover {
@apply transition-all duration-200;
}
.btn-hover:hover {
@apply transform -translate-y-0.5;
}
/* 卡片悬停 */
.card-hover {
@apply transition-all duration-300;
}
.card-hover:hover {
@apply transform -translate-y-0.5 shadow-md;
}
/* 标签悬停 */
.tag-hover {
@apply transition-all duration-300;
}
.tag-hover:hover {
@apply opacity-80 transform scale-105;
}📱 响应式设计
断点系统
/* 移动端 */
@media (max-width: 639px) {
.mobile-only { display: block; }
.desktop-only { display: none; }
}
/* 平板端 */
@media (min-width: 640px) and (max-width: 1023px) {
.tablet-only { display: block; }
}
/* 桌面端 */
@media (min-width: 1024px) {
.desktop-only { display: block; }
.mobile-only { display: none; }
}网格响应式
/* 统计卡片 */
.stats-responsive {
@apply grid gap-3;
grid-template-columns: repeat(1, 1fr); /* 默认 1 列 */
@media (min-width: 640px) {
grid-template-columns: repeat(2, 1fr); /* sm: 2 列 */
}
@media (min-width: 768px) {
grid-template-columns: repeat(3, 1fr); /* md: 3 列 */
}
@media (min-width: 1024px) {
grid-template-columns: repeat(4, 1fr); /* lg: 4 列 */
}
}🎯 主色系使用规范
1. 主色 #ffda44 使用场景
/* 主要按钮 */
.btn-primary {
@apply bg-[#ffda44] hover:bg-[#e6c200] text-gray-900 font-semibold;
}
/* 重要提示 */
.alert-primary {
@apply bg-[#fffdf0] border-[#ffda44] text-gray-800;
}
/* 高亮文本 */
.text-highlight {
@apply text-[#ffda44] font-semibold;
}
/* 进度条 */
.progress-primary {
@apply bg-[#ffda44];
}
/* 徽章 */
.badge-primary {
@apply bg-[#ffda44] text-gray-900;
}2. 渐变色使用
/* 卡片头部 */
.card-header-primary {
background: linear-gradient(135deg, #ffda44 0%, #ffd700 100%);
}
/* 按钮渐变 */
.btn-gradient-primary {
background: linear-gradient(135deg, #ffda44 0%, #ffd700 100%);
}
/* 图标背景 */
.icon-bg-primary {
background: linear-gradient(135deg, #ffda44 0%, #ffd700 100%);
}3. 深色模式适配
/* 深色模式下的主色 */
.dark .btn-primary {
@apply bg-[#e6c200] hover:bg-[#ccad00] text-gray-900;
}
.dark .alert-primary {
@apply bg-[#332a00] border-[#e6c200] text-[#ffda44];
}
.dark .text-highlight {
@apply text-[#e6c200];
}📋 设计原则
1. 统一性原则
- 所有页面使用统一的设计语言
- 保持视觉风格的一致性
- 组件复用最大化
2. 紧凑性原则
- 信息密度优化,减少空白浪费
- 合理利用屏幕空间
- 提升用户操作效率
3. 可读性原则
- 确保文本清晰易读
- 合理的对比度
- 避免文本换行
4. 响应式原则
- 适配各种屏幕尺寸
- 移动端优先设计
- 渐进式增强
🚀 最佳实践
1. 性能优化
- 使用
v-memo缓存复杂计算 - 合理使用
v-show和v-if - 图片懒加载
- 组件按需加载
2. 用户体验
- 加载状态提示
- 错误边界处理
- 操作反馈及时
- 键盘导航支持
3. 可维护性
- 组件职责单一
- 样式模块化
- 类型定义完整
- 文档注释清晰
4. 可扩展性
- 主题色可配置
- 组件参数灵活
- 样式可覆盖
- 功能可扩展
重要提醒:
- 始终遵循设计系统规范
- 确保深色模式兼容性
- 保持视觉一致性
- 优化用户体验
- 遵循响应式设计原则
