Files
Docker/uniapp/youjiala/src/pages/tab/mine.vue
T
2026-10-14 14:48:29 +08:00

173 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
/**
* 底部导航「我的」页:主题外观设置(uView Pro 主题系统)+ 后续个人资料入口占位。
* 主题列表与默认值在 main.ts 注册(common/uview-pro.theme.ts 的四套配色);
* useTheme 的 setTheme/setDarkMode 自带 Storage 持久化(uview-pro-theme 键),
* 冷启动时由插件 initTheme 恢复,这里不需要再接 store。
* 权限暂用 UserOperation(见 routes.ts 的 PAGE_PERMISSIONS);useAuthGuard 兜冷启动直达。
*/
import { useLocale, useTheme } from "uview-pro";
import { useAuthGuard } from "@/composables";
/** 与 uview-pro 内部 DarkMode 联合对齐(顶层未导出该类型,本地声明同构字面量) */
type DarkModeValue = "auto" | "light" | "dark";
const { t } = useLocale();
useAuthGuard();
// currentTheme/darkMode 是包级单例 ref:任意页切换,本页选中态实时跟随
const { themes, currentTheme, setTheme, darkMode, setDarkMode } = useTheme();
const darkOptions: { value: DarkModeValue; label: string }[] = [
{ value: "auto", label: t("MinePage.darkAuto") },
{ value: "light", label: t("MinePage.darkLight") },
{ value: "dark", label: t("MinePage.darkDark") },
];
function onPickTheme(name: string): void {
setTheme(name);
}
function onPickDarkMode(mode: DarkModeValue): void {
setDarkMode(mode);
}
</script>
<template>
<app-page :nav-title="t('MinePage.title')" :show-nav-back="false" :show-tabbar="true">
<view class="mine-page">
<!-- 主题配色:色点取自各主题 primary,选中打勾 -->
<view class="mine-card">
<text class="mine-card__title">
{{ t("MinePage.themeTitle") }}
</text>
<view class="mine-themes">
<view v-for="theme in themes" :key="theme.name" class="mine-theme" @tap="onPickTheme(theme.name)">
<view class="mine-theme__dot"
:class="{ 'mine-theme__dot--active': theme.name === currentTheme?.name }"
:style="{ backgroundColor: theme.color.primary }">
<u-icon v-if="theme.name === currentTheme?.name" name="checkmark" size="30"
color="#ffffff" />
</view>
<text class="mine-theme__label">
{{ theme.label }}
</text>
</view>
</view>
<text class="mine-card__hint">
{{ t("MinePage.themeHint") }}
</text>
</view>
<!-- 深色模式:跟随系统 / 强制浅色 / 强制暗黑 三段 -->
<view class="mine-card">
<text class="mine-card__title">
{{ t("MinePage.darkTitle") }}
</text>
<view class="mine-dark">
<view v-for="opt in darkOptions" :key="opt.value" class="mine-dark__seg"
:class="{ 'mine-dark__seg--active': opt.value === darkMode }" @tap="onPickDarkMode(opt.value)">
<text class="mine-dark__text">
{{ opt.label }}
</text>
</view>
</view>
</view>
</view>
</app-page>
</template>
<style lang="scss" scoped>
.mine-page {
display: flex;
flex-direction: column;
gap: 24rpx;
padding: 24rpx;
}
/* 白底圆角卡片:与文件页分区卡片同一风格语言 */
.mine-card {
padding: 32rpx;
border-radius: 24rpx;
background-color: #ffffff;
}
.mine-card__title {
font-size: 30rpx;
font-weight: 600;
color: #1f2329;
}
.mine-card__hint {
margin-top: 20rpx;
font-size: 24rpx;
color: #9aa0a6;
}
.mine-themes {
display: flex;
align-items: center;
gap: 40rpx;
margin-top: 28rpx;
}
.mine-theme {
display: flex;
flex-direction: column;
align-items: center;
gap: 12rpx;
}
.mine-theme__dot {
display: flex;
align-items: center;
justify-content: center;
width: 88rpx;
height: 88rpx;
border-radius: 50%;
box-shadow: 0 8rpx 16rpx rgba(31, 35, 41, 0.12);
&--active {
border: 6rpx solid #ffffff;
outline: 4rpx solid #1f2329;
}
}
.mine-theme__label {
font-size: 24rpx;
color: #5c626b;
}
/* 三段胶囊:选中段深底白字(跟随 currentTheme primary 的中性替代) */
.mine-dark {
display: flex;
gap: 8rpx;
margin-top: 28rpx;
padding: 8rpx;
border-radius: 999rpx;
background-color: #f2f3f5;
}
.mine-dark__seg {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
height: 64rpx;
border-radius: 999rpx;
&--active {
background-color: #1f2329;
}
}
.mine-dark__text {
font-size: 26rpx;
color: #5c626b;
.mine-dark__seg--active & {
color: #ffffff;
}
}
</style>