Skip to content

useTheme 主题管理

主题管理 composable,提供主题切换、持久化、CSS 变量注入、暗黑模式等功能。

概述

useTheme 是 uView-Pro 的主题管理系统,支持:

  • 多主题切换(品牌色、渐变色等)
  • 主题持久化(保存到 Storage)
  • CSS 变量自动注入
  • 暗黑模式(跟随系统 / 强制亮色 / 强制暗黑)
  • 暗黑模式持久化

引入方式

typescript
import { useTheme } from 'uview-pro';

API

返回值

useTheme() 返回一个包含以下属性和方法的对象:

分类属性/方法类型说明
响应式currentThemeRef<Theme | null>当前主题信息
themesRef<Theme[]>所有可用主题
darkModeRef<DarkMode>暗黑模式设置
cssVarsRef<Record<string, string>>CSS 变量映射
主题方法initTheme(themes?, defaultConfig?, isForce?)function初始化主题系统
setTheme(themeName: string)function切换主题
getCurrentTheme()function获取当前主题
getAvailableThemes()function获取所有可用主题
暗黑模式initDarkMode(darkMode?, isForce?)function初始化暗黑模式
getDarkMode()function获取暗黑模式设置
setDarkMode(mode: DarkMode)function设置暗黑模式
isInDarkMode()function检查是否处于暗黑模式
toggleDarkMode()function切换暗黑模式

响应式引用

currentTheme

当前主题信息(响应式)。

typescript
const { currentTheme } = useTheme();

console.log(currentTheme.value?.name); // 'default'
console.log(currentTheme.value?.color); // 主题颜色配置
console.log(currentTheme.value?.darkColor); // 暗黑模式颜色配置

themes

所有可用主题列表(响应式)。

typescript
const { themes } = useTheme();

console.log(themes.value);
// [
//   { name: 'default', color: {...}, darkColor: {...} },
//   { name: 'dark', color: {...}, darkColor: {...} }
// ]

darkMode

当前暗黑模式设置(响应式)。

typescript
const { darkMode } = useTheme();

console.log(darkMode.value); // 'auto' | 'light' | 'dark'

DarkMode 类型

typescript
type DarkMode = 'auto' | 'light' | 'dark';
  • auto - 跟随系统
  • light - 强制亮色
  • dark - 强制暗黑

cssVars

生成的 CSS 变量映射(响应式)。

typescript
const { cssVars } = useTheme();

console.log(cssVars.value);
// {
//   '--u-type-primary': '#2979ff',
//   '--u-type-success': '#19be6b',
//   '--u-type-warning': '#ff9900',
//   '--u-type-error': '#fa3534',
//   '--u-bg-color': '#ffffff',
//   ...
// }

主题方法

initTheme(themes?, defaultConfig?, isForce?)

初始化主题系统。

typescript
const { initTheme } = useTheme();

// 使用默认内置主题
initTheme();

// 使用自定义主题
const customThemes = [
    {
        name: 'blue',
        color: {
            primary: '#1890ff',
            success: '#52c41a',
            warning: '#faad14',
            error: '#f5222d'
        }
    },
    {
        name: 'purple',
        color: {
            primary: '#722ed1',
            success: '#52c41a',
            warning: '#faad14',
            error: '#f5222d'
        }
    }
];

initTheme(customThemes, 'blue', true);

setTheme(themeName)

切换主题。

typescript
const { setTheme, currentTheme } = useTheme();

// 切换到蓝色主题
setTheme('blue');
console.log(currentTheme.value?.name); // 'blue'

// 切换到紫色主题
setTheme('purple');
console.log(currentTheme.value?.name); // 'purple'

getCurrentTheme()

获取当前主题(非响应式)。

typescript
const { getCurrentTheme } = useTheme();

const theme = getCurrentTheme();
console.log(theme?.name);
console.log(theme?.color);

getAvailableThemes()

获取所有可用主题。

typescript
const { getAvailableThemes } = useTheme();

const themes = getAvailableThemes();
console.log(themes.map(t => t.name)); // ['default', 'blue', 'purple']

暗黑模式方法

initDarkMode(darkMode?, isForce?)

初始化暗黑模式。

typescript
const { initDarkMode } = useTheme();

// 默认跟随系统
initDarkMode();

// 指定暗黑模式
initDarkMode('auto');
initDarkMode('light');
initDarkMode('dark');

// 强制重新初始化
initDarkMode('auto', true);

getDarkMode()

获取当前暗黑模式设置。

typescript
const { getDarkMode } = useTheme();

const mode = getDarkMode();
console.log(mode); // 'auto' | 'light' | 'dark'

setDarkMode(mode)

设置暗黑模式。

typescript
const { setDarkMode, darkMode, isInDarkMode } = useTheme();

// 跟随系统
setDarkMode('auto');

// 强制亮色
setDarkMode('light');

// 强制暗黑
setDarkMode('dark');

console.log(darkMode.value); // 'dark'
console.log(isInDarkMode()); // true(如果系统是暗黑主题)

isInDarkMode()

检查当前是否处于暗黑模式。

typescript
const { isInDarkMode } = useTheme();

if (isInDarkMode()) {
    console.log('当前是暗黑模式');
} else {
    console.log('当前是亮色模式');
}

toggleDarkMode()

切换暗黑模式(在 light 和 dark 之间切换)。

typescript
const { toggleDarkMode, isInDarkMode } = useTheme();

// 切换
toggleDarkMode();

console.log(isInDarkMode()); // 切换后的状态

使用示例

基础主题切换

html
<script setup lang="ts">
import { useTheme } from '@/uni_modules/uview-pro/libs/hooks/useLocale';

const { 
    currentTheme, 
    themes, 
    setTheme, 
    darkMode,
    setDarkMode,
    isInDarkMode 
} = useTheme();

// 主题切换
const onThemeChange = (e: any) => {
    const index = e.detail.value;
    setTheme(themes.value[index].name);
};

// 暗黑模式切换
const onDarkModeChange = (e: any) => {
    const modes = ['auto', 'light', 'dark'];
    setDarkMode(modes[e.detail.value]);
};
</script>

<template>
    <view class="settings">
        <!-- 主题选择 -->
        <picker :value="currentThemeIndex" :range="themeNames" @change="onThemeChange">
            <view class="row">
                <text>主题</text>
                <text>{{ currentTheme?.name }}</text>
            </view>
        </picker>

        <!-- 暗黑模式 -->
        <picker :value="darkModeIndex" :range="darkModeOptions" @change="onDarkModeChange">
            <view class="row">
                <text>暗黑模式</text>
                <text>{{ darkMode }}</text>
            </view>
        </picker>

        <!-- 状态显示 -->
        <view>当前是否暗黑: {{ isInDarkMode() ? '是' : '否' }}</view>
    </view>
</template>

初始化完整主题系统

html
<script setup lang="ts">
import { useTheme } from 'uview-pro';

const { initTheme, initDarkMode, currentTheme, darkMode } = useTheme();

// 定义主题
const themes = [
    {
        name: 'default',
        color: {
            primary: '#2979ff',
            success: '#19be6b',
            warning: '#ff9900',
            error: '#fa3534',
            info: '#909399'
        },
        darkColor: {
            primary: '#2979ff',
            success: '#19be6b',
            warning: '#ff9900',
            error: '#fa3534',
            info: '#909399'
        }
    },
    {
        name: 'dark-theme',
        color: {
            primary: '#4caf50',
            success: '#4caf50',
            warning: '#ff9800',
            error: '#f44336',
            info: '#2196f3'
        },
        darkColor: {
            primary: '#81c784',
            success: '#81c784',
            warning: '#ffb74d',
            error: '#e57373',
            info: '#64b5f6'
        }
    }
];

// 初始化
onMounted(() => {
    initTheme(themes, 'default', true);
    initDarkMode('auto');
});
</script>

结合 CSS 变量使用

html
<script setup lang="ts">
import { useTheme } from 'uview-pro';

const { cssVars, isInDarkMode } = useTheme();

// 动态样式对象
const dynamicStyle = computed(() => ({
    '--primary-color': cssVars.value['--u-type-primary'],
    '--bg-color': cssVars.value['--u-bg-color'],
    '--text-color': cssVars.value['--u-main-color']
}));
</script>

<template>
    <view :style="dynamicStyle" class="container">
        <view class="card">
            <text class="title">卡片标题</text>
            <text class="desc">卡片内容描述</text>
        </view>
    </view>
</template>

<style>
.container {
    background-color: var(--bg-color);
    color: var(--text-color);
}

.card {
    background-color: var(--u-bg-color);
    border: 1px solid var(--u-border-color);
}

.title {
    color: var(--primary-color);
}
</style>

暗黑模式监听

typescript
<script setup lang="ts">
import { useTheme } from 'uview-pro';
import { onShow } from '@dcloudio/uni-app';

const { isInDarkMode } = useTheme();

// 监听页面显示时的暗黑模式状态
onShow(() => {
    if (isInDarkMode()) {
        console.log('当前是暗黑模式');
        // 可以在这里执行暗黑模式相关的初始化操作
    }
});

// 监听主题变化
watch(() => isInDarkMode(), (dark) => {
    if (dark) {
        uni.showToast({ title: '已进入暗黑模式', icon: 'none' });
    } else {
        uni.showToast({ title: '已切换到亮色模式', icon: 'none' });
    }
});
</script>

主题持久化

主题设置会自动保存到本地存储:

  • 主题设置:uview-pro-theme
  • 暗黑模式:uview-pro-dark-mode
typescript
<script setup lang="ts">
import { useTheme } from 'uview-pro';

const { setTheme, setDarkMode } = useTheme();

// 切换主题(会自动保存)
const changeTheme = (name: string) => {
    setTheme(name);
    // 已在内部保存到 Storage,下次打开应用会应用相同主题
};

// 切换暗黑模式(会自动保存)
const changeDarkMode = (mode: 'auto' | 'light' | 'dark') => {
    setDarkMode(mode);
    // 已在内部保存到 Storage
};
</script>

注意事项

  1. 主题和暗黑模式设置会自动持久化到 Storage
  2. isInDarkMode() 返回布尔值,表示当前实际显示状态
  3. darkMode 是设置值,isInDarkMode() 是实际显示状态
  4. CSS 变量会自动注入到页面,无需手动设置
  5. 建议在 App.vue 或入口文件中调用 initTheme 初始化
  6. 暗黑模式切换会触发响应式更新,UI 自动适配