首次提交:初始化项目代码
This commit is contained in:
@@ -0,0 +1,677 @@
|
||||
<template>
|
||||
<view class="theme-page theme-transition" :style="{ background: themeConfig.bgColor }">
|
||||
<!-- 背景装饰 -->
|
||||
<view class="page-decoration deco-1" :style="{ background: themeConfig.primaryColor + '10' }"></view>
|
||||
<view class="page-decoration deco-2" :style="{ background: themeConfig.secondaryColor + '10' }"></view>
|
||||
|
||||
<!-- 页面头部 -->
|
||||
<view class="page-header">
|
||||
<view class="header-decoration">
|
||||
<view class="header-glow" :style="{ background: `radial-gradient(circle, ${themeConfig.primaryColor}20 0%, transparent 70%)` }"></view>
|
||||
</view>
|
||||
<view class="header-title-row">
|
||||
<view class="header-icon-wrap" :style="{ background: themeConfig.primaryColor + '15' }">
|
||||
<text class="header-icon">🎨</text>
|
||||
</view>
|
||||
<view class="header-text">
|
||||
<text class="page-title theme-transition" :style="{ color: themeConfig.textPrimary }">主题皮肤</text>
|
||||
<text class="page-subtitle theme-transition" :style="{ color: themeConfig.textSecondary }">选择你喜欢的配色方案</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="theme-list">
|
||||
<!-- 遍历主题列表 -->
|
||||
<view
|
||||
class="theme-item card theme-transition"
|
||||
v-for="(theme, key) in validThemeList"
|
||||
:key="`theme-${key}`"
|
||||
@click="selectTheme(key)"
|
||||
:style="getThemeItemStyle(theme, key)"
|
||||
>
|
||||
<!-- 主题预览区域 -->
|
||||
<view class="theme-preview"
|
||||
:style="{ background: theme.bgColor }">
|
||||
<view class="preview-shine"></view>
|
||||
<view class="preview-circle-wrap">
|
||||
<view class="preview-circle" :style="{ background: `linear-gradient(135deg, ${theme.primaryColor} 0%, ${theme.secondaryColor} 100%)` }">
|
||||
<view class="preview-circle-inner" :style="{ background: theme.cardBgColor }"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="preview-colors">
|
||||
<view class="preview-color-item primary" :style="{ background: theme.primaryColor }"></view>
|
||||
<view class="preview-color-item secondary" :style="{ background: theme.secondaryColor }"></view>
|
||||
<view class="preview-color-item accent" :style="{ background: theme.warningColor }"></view>
|
||||
<view class="preview-color-item text" :style="{ background: theme.textPrimary }"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 主题信息区 -->
|
||||
<view class="theme-info">
|
||||
<view class="theme-name-row">
|
||||
<text class="theme-name theme-transition" :style="{ color: theme.textPrimary }">
|
||||
{{ theme.name }}
|
||||
</text>
|
||||
<view class="theme-badge" v-if="currentThemeKey === key" :style="{ background: theme.primaryColor }">
|
||||
<text class="badge-text">当前</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="theme-desc theme-transition" :style="{ color: theme.textSecondary }">
|
||||
{{ getThemeDesc(key) }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- 选中标识 -->
|
||||
<view class="active-indicator theme-transition" v-if="currentThemeKey === key">
|
||||
<view class="indicator-ring" :style="{ borderColor: theme.primaryColor }"></view>
|
||||
<view class="indicator-inner" :style="{ background: themeConfig.primaryColor }">
|
||||
<FaIcon icon="check" :size="12" color="#fff" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部提示 -->
|
||||
<view class="bottom-area">
|
||||
<view class="tip-card theme-transition" :style="{ background: themeConfig.cardBgColor }">
|
||||
<view class="tip-icon-wrap" :style="{ background: themeConfig.primaryColor + '15' }">
|
||||
<text class="tip-icon">💡</text>
|
||||
</view>
|
||||
<view class="tip-content">
|
||||
<text class="tip-title theme-transition" :style="{ color: themeConfig.textPrimary }">提示</text>
|
||||
<text class="tip-text theme-transition" :style="{ color: themeConfig.textSecondary }">主题变更将同步到所有页面</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
THEME_PRESETS,
|
||||
getThemeConfigFromStorage,
|
||||
getThemeKeyFromStorage,
|
||||
switchTheme,
|
||||
DEFAULT_THEME_KEY,
|
||||
THEME_CHANGE_EVENT
|
||||
} from '@/utils/theme.js'
|
||||
import { refreshNavBarTheme, forceApplyTabBarTheme } from '@/utils/themeGlobal'
|
||||
import FaIcon from '@/components/FaIcon.vue'
|
||||
|
||||
export default {
|
||||
components: { FaIcon },
|
||||
data() {
|
||||
return {
|
||||
currentThemeKey: '',
|
||||
themeConfig: getThemeConfigFromStorage() || THEME_PRESETS[DEFAULT_THEME_KEY],
|
||||
THEME_PRESETS,
|
||||
isSwitching: false
|
||||
}
|
||||
},
|
||||
// 计算属性:过滤有效主题 + 实时获取配置
|
||||
computed: {
|
||||
// 过滤掉无效的主题配置,避免循环异常
|
||||
validThemeList() {
|
||||
const validThemes = {}
|
||||
Object.keys(THEME_PRESETS).forEach(key => {
|
||||
if (THEME_PRESETS[key]?.name && THEME_PRESETS[key]?.primaryColor) {
|
||||
validThemes[key] = THEME_PRESETS[key]
|
||||
}
|
||||
})
|
||||
return validThemes
|
||||
},
|
||||
// 实时读取最新主题配置(优先级:全局 > 本地 > 默认)
|
||||
currentThemeConfig() {
|
||||
const appInstance = getApp({ allowDefault: true })
|
||||
return appInstance?.globalData?.themeConfig
|
||||
|| getThemeConfigFromStorage()
|
||||
|| THEME_PRESETS[DEFAULT_THEME_KEY]
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.initPage()
|
||||
},
|
||||
onShow() {
|
||||
this.syncThemeState()
|
||||
refreshNavBarTheme()
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off(THEME_CHANGE_EVENT, this.themeChangeHandler)
|
||||
},
|
||||
methods: {
|
||||
initPage() {
|
||||
this.syncThemeState()
|
||||
this.watchThemeChange()
|
||||
},
|
||||
|
||||
syncThemeState() {
|
||||
const appInstance = getApp({ allowDefault: true })
|
||||
this.currentThemeKey = appInstance?.globalData?.themeKey
|
||||
|| getThemeKeyFromStorage()
|
||||
|| DEFAULT_THEME_KEY
|
||||
this.themeConfig = appInstance?.globalData?.themeConfig
|
||||
|| getThemeConfigFromStorage()
|
||||
|| THEME_PRESETS[DEFAULT_THEME_KEY]
|
||||
},
|
||||
|
||||
watchThemeChange() {
|
||||
this.themeChangeHandler = ({ key, config }) => {
|
||||
if (!key || !config) return
|
||||
if (this.currentThemeKey !== key) {
|
||||
this.currentThemeKey = key
|
||||
this.themeConfig = config
|
||||
}
|
||||
}
|
||||
uni.$on(THEME_CHANGE_EVENT, this.themeChangeHandler)
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取主题项样式(简化逻辑 + 性能优化)
|
||||
*/
|
||||
getThemeItemStyle(theme, key) {
|
||||
const isActive = this.currentThemeKey === key
|
||||
return {
|
||||
backgroundColor: theme.cardBgColor,
|
||||
color: theme.textPrimary,
|
||||
borderRadius: '28rpx',
|
||||
boxShadow: `0 6rpx 20rpx ${theme.shadowColor}`,
|
||||
border: `2rpx solid ${isActive ? theme.primaryColor : theme.borderColor}`,
|
||||
marginBottom: isActive ? '0' : '20rpx' // 选中项减少下边距,突出显示
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取主题描述(增强用户认知)
|
||||
*/
|
||||
getThemeDesc(key) {
|
||||
const descMap = {
|
||||
default: '暖阳黄 · 明亮活泼,适合日常',
|
||||
mint: '清新青 · 自然舒适,清爽怡人',
|
||||
cherry: '樱花粉 · 梦幻浪漫,少女心满满',
|
||||
sky: '晴空蓝 · 清爽明亮,干净利落',
|
||||
dark: '深邃夜 · 护眼深色,夜间更舒适',
|
||||
cream: '薰衣草 · 温柔治愈,浪漫梦幻',
|
||||
ocean: '柑橘橙 · 元气满满,活力四射',
|
||||
matcha: '薄荷青 · 清凉冰爽,沁心舒爽'
|
||||
}
|
||||
return descMap[key] || '自定义主题风格'
|
||||
},
|
||||
|
||||
/**
|
||||
* 选择主题(防重复点击 + 友好交互)
|
||||
*/
|
||||
async selectTheme(themeKey) {
|
||||
// 防重复点击 + 合法性校验
|
||||
if (this.isSwitching || this.currentThemeKey === themeKey || !this.validThemeList[themeKey]) {
|
||||
return
|
||||
}
|
||||
|
||||
this.isSwitching = true // 上锁
|
||||
uni.showLoading({ title: '切换中...', mask: true }) // 遮罩防止误操作
|
||||
|
||||
try {
|
||||
// 调用核心切换方法
|
||||
const success = await switchTheme(themeKey)
|
||||
|
||||
if (success) {
|
||||
// 延迟返回,等待提示展示(提升体验)
|
||||
setTimeout(() => {
|
||||
this.jumpToMyPage()
|
||||
}, 800)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '主题已生效,云端同步失败',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
// 同步失败也返回页面
|
||||
setTimeout(() => this.jumpToMyPage(), 2000)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('切换主题异常:', error)
|
||||
uni.showToast({
|
||||
title: '切换失败,请重试',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
this.isSwitching = false // 解锁
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 跳转回我的页面(多层兜底,适配所有场景)
|
||||
*/
|
||||
jumpToMyPage() {
|
||||
const pages = getCurrentPages()
|
||||
// 场景1:从我的页面跳转 → 回退
|
||||
if (pages.length > 1) {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
fail: () => this.forceJumpToMyPage(),
|
||||
success: () => this.postJumpRefresh()
|
||||
})
|
||||
} else {
|
||||
// 场景2:直接打开 → 强制跳转
|
||||
this.forceJumpToMyPage()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 强制跳转我的页面(终极兜底)
|
||||
*/
|
||||
forceJumpToMyPage() {
|
||||
// 优先级:switchTab(tabBar)> redirectTo > navigateTo
|
||||
const jumpMethods = [
|
||||
() => uni.switchTab({
|
||||
url: '/pages/mine/mine',
|
||||
success: () => this.postJumpRefresh(),
|
||||
fail: () => {}
|
||||
}),
|
||||
() => uni.redirectTo({
|
||||
url: '/pages/mine/mine',
|
||||
success: () => this.postJumpRefresh(),
|
||||
fail: () => {}
|
||||
}),
|
||||
() => uni.navigateTo({
|
||||
url: '/pages/mine/mine',
|
||||
success: () => this.postJumpRefresh(),
|
||||
fail: () => {}
|
||||
})
|
||||
]
|
||||
|
||||
// 依次尝试跳转,直到成功
|
||||
const tryJump = (index = 0) => {
|
||||
if (index >= jumpMethods.length) return
|
||||
jumpMethods[index]()
|
||||
setTimeout(() => tryJump(index + 1), 300)
|
||||
}
|
||||
tryJump()
|
||||
},
|
||||
|
||||
/**
|
||||
* 跳转后刷新TabBar样式(关键:确保TabBar颜色立即更新)
|
||||
*/
|
||||
postJumpRefresh() {
|
||||
setTimeout(() => {
|
||||
const appInstance = getApp({ allowDefault: true })
|
||||
if (appInstance?.globalData?.themeConfig) {
|
||||
forceApplyTabBarTheme(appInstance.globalData.themeConfig)
|
||||
}
|
||||
}, 100)
|
||||
setTimeout(() => {
|
||||
const appInstance = getApp({ allowDefault: true })
|
||||
if (appInstance?.globalData?.themeConfig) {
|
||||
forceApplyTabBarTheme(appInstance.globalData.themeConfig)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 页面容器 */
|
||||
.theme-page {
|
||||
padding: 20rpx 24rpx;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 页面装饰 */
|
||||
.page-decoration {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.deco-1 {
|
||||
width: 300rpx;
|
||||
height: 300rpx;
|
||||
top: -100rpx;
|
||||
right: -100rpx;
|
||||
animation: float1 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.deco-2 {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
bottom: 100rpx;
|
||||
left: -60rpx;
|
||||
animation: float2 6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes float1 {
|
||||
0%, 100% { transform: translate(0, 0); }
|
||||
50% { transform: translate(20rpx, 20rpx); }
|
||||
}
|
||||
|
||||
@keyframes float2 {
|
||||
0%, 100% { transform: translate(0, 0); }
|
||||
50% { transform: translate(-15rpx, -15rpx); }
|
||||
}
|
||||
|
||||
/* 页面头部 */
|
||||
.page-header {
|
||||
margin-bottom: 40rpx;
|
||||
padding: 40rpx 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-decoration {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.header-glow {
|
||||
position: absolute;
|
||||
top: -50rpx;
|
||||
left: -50rpx;
|
||||
width: 300rpx;
|
||||
height: 300rpx;
|
||||
}
|
||||
|
||||
.header-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.header-icon-wrap {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 8rpx 24rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
font-size: 44rpx;
|
||||
}
|
||||
|
||||
.header-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 42rpx;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 28rpx;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
/* 主题列表 */
|
||||
.theme-list {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
/* 主题项 */
|
||||
.theme-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 32rpx;
|
||||
border-radius: 12rpx;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.theme-item:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.theme-item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4rpx;
|
||||
background: linear-gradient(90deg, transparent, var(--primaryColor), transparent);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.theme-item.active::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 主题预览区 */
|
||||
.theme-preview {
|
||||
width: 150rpx;
|
||||
height: 110rpx;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 14rpx;
|
||||
margin-right: 28rpx;
|
||||
border: 2rpx solid rgba(0,0,0,0.04);
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.06);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.preview-shine {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 50%;
|
||||
background: linear-gradient(180deg, rgba(255,255,255,0.3) 0%, transparent 100%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.preview-circle-wrap {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.preview-circle {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 6rpx 20rpx rgba(0,0,0,0.12);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.preview-circle-inner {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.preview-colors {
|
||||
display: flex;
|
||||
gap: 8rpx;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.preview-color-item {
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 6rpx;
|
||||
box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.preview-color-item.primary {
|
||||
border-radius: 8rpx 8rpx 2rpx 8rpx;
|
||||
}
|
||||
|
||||
.preview-color-item.secondary {
|
||||
border-radius: 8rpx 8rpx 8rpx 2rpx;
|
||||
}
|
||||
|
||||
.preview-color-item.accent {
|
||||
border-radius: 8rpx 2rpx 8rpx 8rpx;
|
||||
}
|
||||
|
||||
.preview-color-item.text {
|
||||
border-radius: 2rpx 8rpx 8rpx 8rpx;
|
||||
}
|
||||
|
||||
/* 主题信息区 */
|
||||
.theme-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.theme-name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.theme-name {
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.theme-badge {
|
||||
padding: 6rpx 16rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.badge-text {
|
||||
font-size: 20rpx;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.theme-desc {
|
||||
font-size: 26rpx;
|
||||
opacity: 0.7;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* 选中标识 */
|
||||
.active-indicator {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.indicator-ring {
|
||||
position: absolute;
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
border-radius: 50%;
|
||||
border: 3rpx solid;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
animation: ringPulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.indicator-inner {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.check-icon {
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@keyframes ringPulse {
|
||||
0%, 100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.15);
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/* 底部区域 */
|
||||
.bottom-area {
|
||||
padding-bottom: 60rpx;
|
||||
}
|
||||
|
||||
.tip-card {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 20rpx;
|
||||
padding: 28rpx 32rpx;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 6rpx 24rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
.tip-icon-wrap {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
border-radius: 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.tip-icon {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.tip-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6rpx;
|
||||
}
|
||||
|
||||
.tip-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 26rpx;
|
||||
opacity: 0.75;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 全局过渡类 */
|
||||
.theme-transition {
|
||||
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
|
||||
/* 覆盖card基础样式 */
|
||||
.card {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user