refactor(styles): centralize global theme tokens and mixins

This commit is contained in:
nepiedg
2026-04-18 11:12:59 +08:00
parent 9c8583a7fc
commit 58e2d0603b
4 changed files with 521 additions and 185 deletions
+127 -130
View File
@@ -49,177 +49,174 @@ export default {
}
</script>
<style>
<style lang="scss">
page {
background:
radial-gradient(circle at top left, rgba(52, 200, 160, 0.14), transparent 28%),
radial-gradient(circle at top right, rgba(255, 255, 255, 0.78), transparent 24%),
linear-gradient(180deg, #eef3f8 0%, #f5f7fb 38%, #fbfdff 100%);
color: #111827;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
font-size: 28rpx;
line-height: 1.5;
background: $bg-page-gradient;
color: $text-primary;
font-family: $font-family-base;
font-size: $font-lg;
line-height: $line-height-normal;
}
// ---- 容器 ----
.container {
padding: 32rpx;
padding: $spacing-xl;
min-height: 100vh;
box-sizing: border-box;
}
// ---- 统一卡片 ----
.card {
background: rgba(255, 255, 255, 0.82);
border-radius: 28rpx;
padding: 32rpx;
margin-bottom: 24rpx;
border: 2rpx solid rgba(255, 255, 255, 0.64);
box-shadow: 0 10rpx 30rpx rgba(15, 23, 42, 0.06);
backdrop-filter: blur(24rpx);
-webkit-backdrop-filter: blur(24rpx);
@include card-base;
margin-bottom: $spacing-lg;
}
.card-light {
background: rgba(255, 255, 255, 0.62);
.card-solid {
@include card-solid;
margin-bottom: $spacing-lg;
}
.text-primary {
color: #1AA37A;
.card-glass {
@include card-glass;
margin-bottom: $spacing-lg;
}
.text-secondary {
color: #667085;
.card-elevated {
@include card-elevated;
margin-bottom: $spacing-lg;
}
.text-muted {
color: #98A2B3;
.card-subtle {
@include card-subtle;
}
.text-center {
text-align: center;
}
// ---- 文字工具类 ----
.text-primary { color: $color-primary-dark; }
.text-secondary { color: $text-secondary; }
.text-muted { color: $text-muted; }
.text-center { text-align: center; }
.text-bold { font-weight: $font-weight-semibold; }
.text-bold {
font-weight: 600;
}
// ---- Flex 工具类 ----
.flex { display: flex; }
.flex-center { @include flex-center; }
.flex-between { @include flex-between; }
.flex-col { @include flex-col; }
.flex-1 { flex: 1; }
.flex {
display: flex;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex-col {
display: flex;
flex-direction: column;
}
.flex-1 {
flex: 1;
}
.gap-sm {
gap: 16rpx;
}
.gap-md {
gap: 24rpx;
}
.gap-lg {
gap: 32rpx;
}
.mt-sm {
margin-top: 16rpx;
}
.mt-md {
margin-top: 24rpx;
}
.mt-lg {
margin-top: 32rpx;
}
.mb-sm {
margin-bottom: 16rpx;
}
.mb-md {
margin-bottom: 24rpx;
}
.mb-lg {
margin-bottom: 32rpx;
}
// ---- 间距工具类 ----
.gap-sm { gap: $spacing-md; }
.gap-md { gap: $spacing-lg; }
.gap-lg { gap: $spacing-xl; }
.mt-sm { margin-top: $spacing-md; }
.mt-md { margin-top: $spacing-lg; }
.mt-lg { margin-top: $spacing-xl; }
.mb-sm { margin-bottom: $spacing-md; }
.mb-md { margin-bottom: $spacing-lg; }
.mb-lg { margin-bottom: $spacing-xl; }
// ---- 统一按钮 ----
.btn {
display: flex;
align-items: center;
justify-content: center;
@include btn-base;
height: 96rpx;
border-radius: 999rpx;
font-size: 32rpx;
font-weight: 600;
font-size: $font-2xl;
}
.btn-primary {
background: linear-gradient(180deg, #32c59d 0%, #1aa37a 100%);
color: #FFFFFF;
box-shadow: 0 12rpx 28rpx rgba(26, 163, 122, 0.22);
@include btn-primary;
}
.btn-secondary {
background: rgba(255, 255, 255, 0.82);
color: #111827;
border: 2rpx solid rgba(15, 23, 42, 0.08);
@include btn-secondary;
}
.btn-outline {
background-color: transparent;
color: #1AA37A;
border: 2rpx solid rgba(26, 163, 122, 0.32);
@include btn-outline;
}
.glass-card {
background: rgba(255, 255, 255, 0.68);
border: 2rpx solid rgba(255, 255, 255, 0.66);
box-shadow: 0 12rpx 32rpx rgba(15, 23, 42, 0.07);
backdrop-filter: blur(28rpx);
-webkit-backdrop-filter: blur(28rpx);
// ---- 统一标签 ----
.chip {
@include chip;
}
.surface-card {
background: rgba(255, 255, 255, 0.9);
border: 2rpx solid rgba(15, 23, 42, 0.06);
box-shadow: 0 10rpx 30rpx rgba(15, 23, 42, 0.05);
.chip-primary {
@include chip-primary;
}
.pill-chip {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 12rpx 22rpx;
border-radius: 999rpx;
background: rgba(255, 255, 255, 0.72);
border: 2rpx solid rgba(255, 255, 255, 0.68);
color: #475467;
font-size: 22rpx;
font-weight: 600;
.chip-muted {
@include chip-muted;
}
.badge {
@include badge;
}
// ---- 进度条 ----
.progress-bar {
@include progress-bar;
}
.progress-fill {
@include progress-fill;
}
.progress-fill-done {
@include progress-fill;
background: linear-gradient(90deg, $color-primary, $color-primary-light);
}
.progress-fill-pending {
@include progress-fill;
background: rgba($color-primary, 0.3);
}
// ---- 圆环 ----
.ring {
@include ring;
}
.ring-inner {
@include ring-inner;
width: 82rpx;
height: 82rpx;
}
.ring-value {
font-size: $font-sm;
font-weight: $font-weight-bold;
color: $text-primary;
}
.ring-label {
font-size: $font-xs;
color: $text-muted;
}
// ---- 安全区域 ----
.safe-area-bottom {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
@include safe-area-bottom;
}
// ---- 底部占位 ----
.bottom-safe {
height: calc(#{$spacing-xl} + env(safe-area-inset-bottom));
}
// ---- 骨架屏动画 ----
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
@keyframes fabFloat {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-6rpx); }
}
// ---- 分割线 ----
.divider {
height: 1px;
background: $border-divider;
margin: 0;
}
</style>
+250
View File
@@ -0,0 +1,250 @@
// ==========================================
// 统一 SCSS Mixins
// ==========================================
// ---- 卡片 ----
@mixin card-base {
background: $bg-card-glass;
border-radius: $radius-xl;
padding: $spacing-lg;
border: 1.5rpx solid $border-card;
box-shadow: $shadow-card;
}
@mixin card-solid {
background: $bg-card;
border-radius: $radius-2xl;
padding: $spacing-xl;
box-shadow: $shadow-sm;
}
@mixin card-glass {
background: $bg-card-glass;
border-radius: $radius-xl;
padding: $spacing-lg;
border: 1.5rpx solid $border-card;
box-shadow: $shadow-card;
-webkit-backdrop-filter: blur(12px);
backdrop-filter: blur(12px);
}
@mixin card-elevated {
@include card-base;
box-shadow: $shadow-md;
border-color: $border-light;
}
@mixin card-subtle {
background: $gradient-card-subtle;
border-radius: $radius-md;
padding: $spacing-lg;
border: 1rpx solid $border-light;
box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.9);
}
// ---- 按钮 ----
@mixin btn-base {
display: flex;
align-items: center;
justify-content: center;
border-radius: $radius-full;
font-weight: $font-weight-bold;
transition: all $transition-fast;
}
@mixin btn-primary {
@include btn-base;
height: 96rpx;
background: $gradient-primary;
color: $text-inverse;
font-size: $font-lg;
box-shadow: $shadow-btn;
}
@mixin btn-secondary {
@include btn-base;
height: 96rpx;
background: $bg-card;
color: $text-primary;
font-size: $font-lg;
border: 2rpx solid $border-light;
box-shadow: $shadow-sm;
}
@mixin btn-outline {
@include btn-base;
height: 96rpx;
background: transparent;
color: $color-primary-dark;
font-size: $font-lg;
border: 2rpx solid rgba($color-primary, 0.32);
}
@mixin btn-pill {
@include btn-base;
padding: $spacing-xs $spacing-lg;
font-size: $font-sm;
font-weight: $font-weight-semibold;
}
// ---- 标签/徽章 ----
@mixin chip {
display: inline-flex;
align-items: center;
justify-content: center;
padding: $spacing-xs $spacing-md;
border-radius: $radius-full;
font-size: $font-sm;
font-weight: $font-weight-semibold;
}
@mixin chip-primary {
@include chip;
background: $color-primary-bg;
color: $color-primary-dark;
border: 1rpx solid $color-primary-border;
}
@mixin chip-muted {
@include chip;
background: $bg-muted;
color: $text-muted;
}
@mixin badge {
@include chip;
font-size: $font-xs;
padding: 6rpx 14rpx;
background: $color-primary-bg;
color: $color-primary-dark;
}
// ---- 进度条 ----
@mixin progress-bar($height: 10rpx) {
height: $height;
background: rgba($color-primary, 0.1);
border-radius: $radius-full;
overflow: hidden;
}
@mixin progress-fill {
height: 100%;
border-radius: $radius-full;
background: linear-gradient(90deg, $color-primary, $color-primary-light);
transition: width $transition-slow;
}
// ---- 圆环 ----
@mixin ring($size: 110rpx) {
width: $size;
height: $size;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
@mixin ring-inner {
border-radius: 50%;
background: $bg-card;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx $color-primary-shadow;
}
// ---- 布局 ----
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
@mixin flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
@mixin flex-col {
display: flex;
flex-direction: column;
}
// ---- 文字 ----
@mixin text-number {
font-family: $font-family-number;
font-weight: $font-weight-heavy;
}
@mixin text-heading {
font-weight: $font-weight-bold;
color: $text-primary;
}
@mixin text-label {
font-size: $font-sm;
color: $text-tertiary;
}
@mixin text-kicker {
font-size: $font-xs;
font-weight: $font-weight-semibold;
color: $text-muted;
}
// ---- 动画骨架 ----
@mixin skeleton-shimmer {
background: linear-gradient(90deg, #E5E7EB 25%, #F3F4F6 50%, #E5E7EB 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
// ---- 安全区域 ----
@mixin safe-area-bottom {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
// ---- 悬浮按钮 ----
@mixin fab {
position: fixed;
z-index: 100;
border-radius: $radius-full;
background: $gradient-primary;
box-shadow: $shadow-fab;
display: flex;
align-items: center;
justify-content: center;
animation: fabFloat 3.6s ease-in-out infinite;
}
// ---- 空状态 ----
@mixin empty-state {
@include flex-col;
align-items: center;
padding: 80rpx $spacing-xl;
border-radius: $radius-2xl;
background: $gradient-card;
box-shadow: $shadow-md;
}
// ---- 菜单项 ----
@mixin menu-item {
display: flex;
align-items: center;
gap: $spacing-lg;
padding: $spacing-lg 0;
background: transparent;
}
@mixin menu-icon($bg: $color-primary-soft) {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
@include flex-center;
flex-shrink: 0;
background: $bg;
}
+112
View File
@@ -0,0 +1,112 @@
// ==========================================
// 薄荷绿浅色系主题 - 统一设计变量
// ==========================================
// ---- 主色调 (薄荷绿) ----
$color-primary: #34C8A0;
$color-primary-dark: #1AA37A;
$color-primary-deeper: #14936d;
$color-primary-light: #6ee7be;
$color-primary-soft: #E6F7F1;
$color-primary-softer: #F0FDF9;
$color-primary-bg: rgba(52, 200, 160, 0.08);
$color-primary-border: rgba(52, 200, 160, 0.14);
$color-primary-shadow: rgba(52, 200, 160, 0.12);
// ---- 功能色 ----
$color-success: #10B981;
$color-warning: #F59E0B;
$color-warning-bg: #FEF3C7;
$color-warning-text: #D97706;
$color-danger: #EF4444;
$color-danger-bg: rgba(239, 68, 68, 0.06);
$color-info: #3B82F6;
$color-info-bg: rgba(59, 130, 246, 0.08);
// ---- 文字色 ----
$text-primary: #111827;
$text-secondary: #4b5563;
$text-tertiary: #6b7280;
$text-muted: #9ca3af;
$text-disabled: #d1d5db;
$text-inverse: #ffffff;
$text-accent: $color-primary-dark;
// ---- 背景色 ----
$bg-page: #F5F8F6;
$bg-page-gradient: linear-gradient(180deg, $color-primary-soft 0%, $color-primary-softer 40%, #FAFFFE 100%);
$bg-card: #ffffff;
$bg-card-glass: rgba(255, 255, 255, 0.88);
$bg-card-hover: #f7faf8;
$bg-subtle: #fbfcfc;
$bg-muted: #f3f4f6;
// ---- 边框 ----
$border-light: rgba(15, 23, 42, 0.06);
$border-card: $color-primary-border;
$border-divider: #f0f0f0;
// ---- 圆角 ----
$radius-xs: 8rpx;
$radius-sm: 12rpx;
$radius-md: 16rpx;
$radius-lg: 20rpx;
$radius-xl: 24rpx;
$radius-2xl: 32rpx;
$radius-full: 999rpx;
// ---- 间距 ----
$spacing-xs: 8rpx;
$spacing-sm: 12rpx;
$spacing-md: 16rpx;
$spacing-lg: 24rpx;
$spacing-xl: 32rpx;
$spacing-2xl: 40rpx;
$spacing-page: 28rpx;
// ---- 阴影 ----
$shadow-sm: 0 4rpx 12rpx rgba(52, 200, 160, 0.06);
$shadow-card: 0 4rpx 18rpx rgba(52, 200, 160, 0.07);
$shadow-md: 0 8rpx 24rpx rgba(15, 23, 42, 0.06);
$shadow-lg: 0 18rpx 36rpx rgba(15, 23, 42, 0.08);
$shadow-btn: 0 12rpx 28rpx rgba(52, 200, 160, 0.22);
$shadow-fab: 0 18rpx 36rpx rgba(52, 200, 160, 0.3);
// ---- 字号 ----
$font-xs: 20rpx;
$font-sm: 22rpx;
$font-base: 24rpx;
$font-md: 26rpx;
$font-lg: 28rpx;
$font-xl: 30rpx;
$font-2xl: 34rpx;
$font-3xl: 40rpx;
$font-4xl: 52rpx;
$font-display: 74rpx;
// ---- 字重 ----
$font-weight-normal: 400;
$font-weight-medium: 500;
$font-weight-semibold: 600;
$font-weight-bold: 700;
$font-weight-heavy: 800;
// ---- 行高 ----
$line-height-tight: 1.2;
$line-height-normal: 1.5;
$line-height-relaxed: 1.7;
// ---- 字体 ----
$font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
$font-family-number: 'DIN Alternate', $font-family-base;
// ---- 渐变 ----
$gradient-primary: linear-gradient(180deg, $color-primary 0%, $color-primary-dark 100%);
$gradient-primary-soft: linear-gradient(180deg, $color-primary-soft 0%, $color-primary-softer 100%);
$gradient-card: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(248, 251, 249, 0.94) 100%);
$gradient-card-subtle: linear-gradient(180deg, $bg-subtle 0%, $bg-card-hover 100%);
// ---- 动画 ----
$transition-fast: 0.2s ease;
$transition-normal: 0.3s ease;
$transition-slow: 0.5s ease;
+32 -55
View File
@@ -1,76 +1,53 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
*
* 薄荷绿浅色系主题 - uni-app 全局 SCSS 变量
* 所有页面自动注入,无需手动 import
*/
/**
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
@import './styles/variables';
@import './styles/mixins';
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 覆盖 uni-app 默认颜色变量 */
$uni-color-primary: $color-primary-dark;
$uni-color-success: $color-success;
$uni-color-warning: $color-warning;
$uni-color-error: $color-danger;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
$uni-text-color: $text-primary;
$uni-text-color-inverse: $text-inverse;
$uni-text-color-grey: $text-tertiary;
$uni-text-color-placeholder: $text-muted;
$uni-text-color-disable: $text-disabled;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
$uni-bg-color: $bg-card;
$uni-bg-color-grey: $bg-page;
$uni-bg-color-hover: $bg-card-hover;
$uni-bg-color-mask: rgba(0, 0, 0, 0.4);
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
$uni-border-color: $border-divider;
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16px;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
$uni-font-size-sm: $font-sm;
$uni-font-size-base: $font-base;
$uni-font-size-lg: $font-md;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-sm: $radius-xs;
$uni-border-radius-base: $radius-sm;
$uni-border-radius-lg: $radius-md;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
$uni-spacing-row-sm: $spacing-xs;
$uni-spacing-row-base: $spacing-md;
$uni-spacing-row-lg: $spacing-lg;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
$uni-spacing-col-sm: $spacing-xs;
$uni-spacing-col-base: $spacing-sm;
$uni-spacing-col-lg: $spacing-md;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;
$uni-opacity-disabled: 0.3;