设计系统
🎨 设计理念
现代简约的设计理念,注重用户体验和移动端优化,为移动端财务管理提供直观、高效的界面设计。
🌈 色彩系统
主色系 - 金黄色 #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">
<!-- 1. 页面头部 -->
<div class="page-header">
<div class="header-content">
<div class="header-left">
<div class="header-icon">
<span class="i-{icon} text-white text-xl" />
</div>
<div class="header-text">
<h2 class="page-title">页面标题</h2>
<p class="page-subtitle">页面副标题</p>
</div>
</div>
<div class="header-right">
<button class="btn-primary">
<span class="i-{icon} mr-1" />
主要操作
</button>
</div>
</div>
</div>
<!-- 2. 页面内容 -->
<div class="page-content">
<!-- 内容区域 -->
</div>
</div>
</template>网格系统
/* 统计卡片布局 */
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 12px;
}
/* 响应式列数 */
.responsive-grid {
display: grid;
grid-template-columns: repeat(1, 1fr); /* 默认 1 列 */
gap: 12px;
}
@media (min-width: 640px) {
.responsive-grid {
grid-template-columns: repeat(2, 1fr); /* sm: 2 列 */
}
}
@media (min-width: 768px) {
.responsive-grid {
grid-template-columns: repeat(3, 1fr); /* md: 3 列 */
}
}🧩 组件规范
统计卡片 (StatCard)
<template>
<div class="stat-card">
<div class="card-header">
<div class="card-icon">
<span class="i-{icon} text-white text-base" />
</div>
<div class="card-info">
<h3 class="card-title">{{ title }}</h3>
<p class="card-subtitle">{{ subtitle }}</p>
</div>
</div>
<div class="card-content">
<div class="card-value">
{{ prefix }}{{ formatValue(value) }}
</div>
<div class="card-footnote">
{{ footnote }}
</div>
</div>
</div>
</template>
<style scoped>
.stat-card {
@apply bg-white rounded-xl p-3 shadow-sm border border-gray-100;
}
.card-header {
@apply flex items-center gap-2 mb-2;
}
.card-icon {
@apply w-8 h-8 rounded-lg bg-gradient-to-br flex items-center justify-center;
}
.card-info {
@apply flex-1 min-w-0;
}
.card-title {
@apply text-sm font-semibold text-gray-800 truncate;
}
.card-subtitle {
@apply text-xs text-gray-500 truncate;
}
.card-content {
@apply text-right;
}
.card-value {
@apply text-lg font-bold text-gray-900;
}
.card-footnote {
@apply text-xs text-gray-500;
}
</style>列表组件
<template>
<div class="list-container">
<div class="list-item" v-for="item in items" :key="item.id">
<div class="item-left">
<div class="item-icon">
<span class="i-{item.icon} text-white text-sm" />
</div>
<div class="item-content">
<h4 class="item-title">{{ item.title }}</h4>
<p class="item-subtitle">{{ item.subtitle }}</p>
</div>
</div>
<div class="item-right">
<div class="item-value">{{ item.value }}</div>
<div class="item-action">
<span class="i-{icon} text-gray-400 text-sm" />
</div>
</div>
</div>
</div>
</template>
<style scoped>
.list-container {
@apply bg-white rounded-xl shadow-sm border border-gray-100;
}
.list-item {
@apply flex items-center justify-between p-3 border-b border-gray-100 last:border-b-0;
}
.item-left {
@apply flex items-center gap-3 flex-1 min-w-0;
}
.item-icon {
@apply w-8 h-8 rounded-lg bg-gradient-to-br flex items-center justify-center;
}
.item-content {
@apply flex-1 min-w-0;
}
.item-title {
@apply text-sm font-semibold text-gray-800 truncate;
}
.item-subtitle {
@apply text-xs text-gray-500 truncate;
}
.item-right {
@apply flex items-center gap-2;
}
.item-value {
@apply text-sm font-semibold text-gray-900;
}
.item-action {
@apply flex items-center;
}
</style>表单组件
<template>
<div class="form-container">
<div class="form-item" v-for="field in fields" :key="field.key">
<label class="form-label">{{ field.label }}</label>
<div class="form-input">
<input
v-model="formData[field.key]"
:type="field.type"
:placeholder="field.placeholder"
class="input-field"
/>
</div>
</div>
<div class="form-actions">
<button class="btn-secondary" @click="handleCancel">取消</button>
<button class="btn-primary" @click="handleSubmit">确定</button>
</div>
</div>
</template>
<style scoped>
.form-container {
@apply bg-white rounded-xl p-4 shadow-sm border border-gray-100;
}
.form-item {
@apply mb-4 last:mb-0;
}
.form-label {
@apply block text-sm font-semibold text-gray-700 mb-2;
}
.form-input {
@apply relative;
}
.input-field {
@apply w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent;
}
.form-actions {
@apply flex gap-3 mt-6;
}
.btn-primary {
@apply flex-1 bg-blue-500 text-white py-2 px-4 rounded-lg font-semibold;
}
.btn-secondary {
@apply flex-1 bg-gray-100 text-gray-700 py-2 px-4 rounded-lg font-semibold;
}
</style>📝 字体规范
字体大小层级
/* 页面标题 */
.text-page-title {
@apply text-xl font-bold text-gray-800;
}
/* 卡片标题 */
.text-card-title {
@apply text-sm font-semibold text-gray-800;
}
/* 列表标题 */
.text-list-title {
@apply text-sm font-semibold text-gray-800;
}
/* 正文内容 */
.text-body {
@apply text-sm text-gray-600;
}
/* 辅助文字 */
.text-caption {
@apply text-xs text-gray-500;
}
/* 数值显示 */
.text-value {
@apply text-base font-bold text-gray-900;
}
/* 小数值 */
.text-value-small {
@apply text-sm font-semibold text-gray-800;
}文本处理
/* 不换行 */
.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 { padding: 4px; }
.p-sm { padding: 8px; }
.p-md { padding: 12px; }
.p-lg { padding: 16px; }
.p-xl { padding: 20px; }
.p-2xl { padding: 24px; }
/* 外边距 */
.m-xs { margin: 4px; }
.m-sm { margin: 8px; }
.m-md { margin: 12px; }
.m-lg { margin: 16px; }
.m-xl { margin: 20px; }
.m-2xl { margin: 24px; }
/* 间距 */
.gap-xs { gap: 4px; }
.gap-sm { gap: 8px; }
.gap-md { gap: 12px; }
.gap-lg { gap: 16px; }
.gap-xl { gap: 20px; }组件间距
/* 页面级间距 */
.page-spacing {
@apply px-4 py-6;
}
/* 卡片间距 */
.card-spacing {
@apply p-3;
}
/* 列表间距 */
.list-spacing {
@apply p-3;
}
/* 表单间距 */
.form-spacing {
@apply p-4;
}
/* 网格间距 */
.grid-spacing {
@apply gap-3;
}✨ 动画效果
页面动画
/* 页面进入动画 */
.page-enter {
animation: slideInUp 0.3s ease-out;
}
@keyframes slideInUp {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
/* 页面退出动画 */
.page-leave {
animation: slideOutDown 0.3s ease-in;
}
@keyframes slideOutDown {
from {
transform: translateY(0);
opacity: 1;
}
to {
transform: translateY(20px);
opacity: 0;
}
}交互动画
/* 按钮悬停 */
.btn-hover {
@apply transition-all duration-200;
}
.btn-hover:hover {
@apply transform scale-105;
}
/* 卡片悬停 */
.card-hover {
@apply transition-all duration-300;
}
.card-hover:hover {
@apply transform -translate-y-1 shadow-md;
}
/* 列表项悬停 */
.list-item-hover {
@apply transition-all duration-200;
}
.list-item-hover:hover {
@apply bg-gray-50;
}📱 响应式设计
断点系统
/* 移动端 */
@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 {
display: grid;
grid-template-columns: repeat(1, 1fr); /* 默认 1 列 */
gap: 12px;
}
@media (min-width: 640px) {
.stats-responsive {
grid-template-columns: repeat(2, 1fr); /* sm: 2 列 */
}
}
@media (min-width: 768px) {
.stats-responsive {
grid-template-columns: repeat(3, 1fr); /* md: 3 列 */
}
}🎯 主色系使用规范
1. 主色 #ffda44 使用场景
/* 主要按钮 */
.btn-primary {
@apply bg-[#ffda44] 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] 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. 可扩展性
- 主题色可配置
- 组件参数灵活
- 样式可覆盖
- 功能可扩展
📱 平台适配
微信小程序
/* 微信小程序特有样式 */
.wechat-specific {
/* 微信小程序特有样式 */
}支付宝小程序
/* 支付宝小程序特有样式 */
.alipay-specific {
/* 支付宝小程序特有样式 */
}H5
/* H5 特有样式 */
.h5-specific {
/* H5 特有样式 */
}App
/* App 特有样式 */
.app-specific {
/* App 特有样式 */
}重要提醒:
- 始终遵循设计系统规范
- 确保移动端兼容性
- 保持视觉一致性
- 优化用户体验
- 遵循响应式设计原则
