多主题与主题切换
13:16概述
项目内置了完整的多主题支持系统,包括亮色主题和深色主题。用户可以根据系统设置或手动选择,实时切换应用的颜色主题,提供更好的用户体验。
项目特性
- 🎨 亮色/深色主题 - 内置亮色和深色两个主题
- 🔄 实时切换 - 无需刷新页面,即时切换主题
- 💾 记住偏好 - 主题选择会自动保存
- 🌈 自定义配置 - 轻松扩展和自定义主题颜色
- 📱 系统适配 - 支持跟随系统主题设置
主题配置文件
theme.json 配置
src/theme.json 定义了应用的主题颜色:
json
{
"light": {
"bgColor": "#fcfcfc", // 背景颜色
"bgColorBottom": "#fcfcfc", // 底部背景
"bgColorTop": "#ff6b00", // 顶部背景
"bgTxtStyle": "dark", // 背景上的文字样式
"navBgColor": "#ff6b00", // 导航栏背景
"navTxtStyle": "white", // 导航栏文字样式
"tabBgColor": "#fcfcfc", // Tabbar 背景
"tabBorderStyle": "black", // Tabbar 边框样式
"tabFontColor": "#1f2937", // Tabbar 文字颜色
"tabSelectedColor": "#ff6b00" // Tabbar 选中颜色
},
"dark": {
"bgColor": "#181818",
"bgColorBottom": "#181818",
"bgColorTop": "#ff6b00",
"bgTxtStyle": "light",
"navBgColor": "#ff6b00",
"navTxtStyle": "white",
"tabBgColor": "#181818",
"tabBorderStyle": "white",
"tabFontColor": "#f3f4f6",
"tabSelectedColor": "#ff6b00"
}
}uView Pro 主题配置
src/common/uview-pro.theme.ts 定义了 uView Pro 组件库的主题:
typescript
// 此文件定义 uView Pro 组件库的多个主题
// 默认主题为 'green',可在 main.ts 中修改
export default {
green: {
// primary 主题色
primary: '#07c160',
// 其他主题颜色...
},
// 其他主题定义...
}初始化设置
main.ts 中的注册主题
typescript
import themes from '@/common/uview-pro.theme'
import uViewPro from 'uview-pro'
app.use(uViewPro, {
theme: {
themes,
defaultTheme: 'green', // 默认主题名称
defaultDarkMode: 'light', // 默认暗黑模式('light'|'dark'|'auto')
}
})pages.json 中的主题应用
json
{
"globalStyle": {
"backgroundColor": "@bgColor",
"backgroundColorBottom": "@bgColorBottom",
"backgroundColorTop": "@bgColorTop",
"backgroundTextStyle": "@bgTxtStyle",
"navigationBarBackgroundColor": "#000000",
"navigationBarTextStyle": "@navTxtStyle"
}
}基本使用
在组件中切换主题
vue
<script setup lang="ts">
import { useTheme } from 'uview-pro'
const { darkMode, getAvailableThemes, currentTheme, setTheme, toggleDarkMode } = useTheme()
const themeNames = getAvailableThemes().map(theme => theme.name)
function handleThemeToggle() {
setTheme(themeNames[Math.floor(Math.random() * themeNames.length)])
}
function handleDarkModeToggle() {
toggleDarkMode()
}
</script>
<template>
<view class="theme-switcher">
<text>当前主题:{{ currentTheme?.label }}</text>
<u-button type="primary" @click="handleThemeToggle">
切换主题
</u-button>
<text>当前暗黑主题:{{ darkMode }}</text>
<u-button type="primary" @click="handleDarkModeToggle">
切换暗黑主题
</u-button>
</view>
</template>根据主题条件渲染
vue
<script setup lang="ts">
import { useTheme } from 'uview-pro'
const { darkMode } = useTheme()
</script>
<template>
<view v-if="darkMode === 'light'" class="light-theme">
亮色主题内容
</view>
<view v-else class="dark-theme">
深色主题内容
</view>
</template>高级用法
自定义单主题颜色
修改系统主题的颜色色值:
typescript
import uViewPro from 'uview-pro'
app.use(uViewPro, {
theme: {
primary: '#9c27b0',
success: '#07c160',
warning: '#fa8919',
danger: '#ff5252',
error: '#ff5252',
info: '#909399',
}
})自定义多主题颜色
扩展 src/common/uview-pro.theme.ts:
typescript
export default {
// 绿色主题
green: {
primary: '#07c160',
success: '#07c160',
warning: '#fa8919',
danger: '#ff5252',
error: '#ff5252',
info: '#909399',
},
// 橙色主题
orange: {
primary: '#ff6b00',
success: '#07c160',
warning: '#fa8919',
danger: '#ff5252',
error: '#ff5252',
info: '#909399',
},
// 蓝色主题
blue: {
primary: '#3498db',
success: '#07c160',
warning: '#fa8919',
danger: '#ff5252',
error: '#ff5252',
info: '#909399',
},
// 紫色主题
purple: {
primary: '#9c27b0',
success: '#07c160',
warning: '#fa8919',
danger: '#ff5252',
error: '#ff5252',
info: '#909399',
},
}然后在 main.ts 中的注册主题
typescript
import themes from '@/common/uview-pro.theme'
import uViewPro from 'uview-pro'
app.use(uViewPro, {
theme: {
themes,
defaultTheme: 'green', // 默认主题名称
defaultDarkMode: 'light', // 默认暗黑模式('light'|'dark'|'auto')
}
})主题选择界面
vue
<script setup lang="ts">
import type { DarkMode } from 'uview-pro/types/global'
import { useTheme } from 'uview-pro'
import { ref } from 'vue'
const { darkMode, currentTheme, setDarkMode, setTheme, getAvailableThemes } = useTheme()
const darkModes = ref<{ value: DarkMode, label: string }[]>(
[
{ value: 'auto', label: '自动' },
{ value: 'light', label: '亮色' },
{ value: 'dark', label: '深色' },
],
)
function handleThemeSelect(theme: string) {
// 切换到选定的主题
setTheme(theme)
}
function handleDarkModeSelect(mode: DarkMode) {
setDarkMode(mode)
}
</script>
<template>
<view class="theme-settings">
<view class="section">
<text class="title">
主题选择
</text>
<view class="theme-grid">
<view
v-for="theme in getAvailableThemes()"
:key="theme.name" class="theme-item"
@click="handleThemeSelect(theme.name)"
>
<view class="color-box" :style="{ 'background-color': theme.color.primary }">
<u-icon v-if="currentTheme?.name === theme.name" name="checkbox-mark" />
</view>
<text>{{ theme.label }}</text>
</view>
</view>
</view>
<view class="section">
<text class="title">
暗黑模式选择
</text>
<view class="mode-list">
<view
v-for="mode in darkModes"
:key="mode.value" class="mode-item"
:class="{ active: darkMode === mode.value }"
@click="handleDarkModeSelect(mode.value)"
>
<text>{{ mode.label }}</text>
<u-icon v-if="darkMode === mode.value" name="checkbox-mark" />
</view>
</view>
</view>
</view>
</template>
<style scoped lang="scss">
.theme-settings {
padding: 16px;
.section {
margin-bottom: 24px;
}
.title {
display: block;
font-size: 14px;
font-weight: 600;
margin-bottom: 12px;
}
.theme-grid {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.theme-item {
text-align: center;
.color-box {
width: 48px;
height: 48px;
border-radius: 8px;
margin-bottom: 8px;
background-color: var(--u-type-primary);
color: white;
display: flex;
justify-content: center;
}
text {
font-size: 12px;
}
}
.mode-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.mode-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px;
border: 1px solid var(--u-border-color);
border-radius: 8px;
transition: all 0.3s;
&.active {
background-color: var(--u-type-primary);
color: white;
border-color: var(--u-type-primary);
}
}
}
</style>最佳实践
- 颜色一致性 - 确保所有主题中的颜色使用一致且具有良好的对比度
- 可访问性 - 考虑色盲用户,避免仅用颜色区分内容
- 性能优化 - 使用 CSS 变量而不是动态计算主题颜色
- 默认选择 - 根据用户的系统设置选择默认主题
- 过渡效果 - 为主题切换添加平滑的过渡动画
- 测试覆盖 - 在所有主题下测试应用外观和功能
- 文档化 - 记录主题色值和使用规则
常见问题
主题切换不生效
检查:
- 确认在
main.ts中注册了uViewPro及多主题 - 确认已经使用
u-config-provider来包裹所有页面 - 确认主题配置已正确加载
- 检查样式是否正确应用
深色模式下文字不清晰
调整 CSS 变量中的文字颜色,确保足够的对比度。
如何添加新主题?
在 src/common/uview-pro.theme.ts 中添加新的主题定义,然后在应用中选择使用。
