vue3+tdesign实现明暗主题切换

很多项目中有些会涉及到明暗主题切换的功能,今天就来梳理一下有关这方面的具体实现步骤和使用到的方法,本篇文章使用到的组件是tdesign,利用部分案例,主要阐述明暗主题切换的技术原理和实现步骤,仅供参考。

目录

一、技术原理与核心

二、实现步骤详解

1.组件搭建

2.状态持久化

 3.模式切换逻辑

 4.组件挂载

5.事件监听

 6.配置与优化

7.使用

三、全部代码


一、技术原理与核心

TDesign 通过 CSS 自定义属性(变量)实现主题切换,所有颜色相关配置均使用 var() 函数引用变量。现代浏览器已广泛支持该特性,TDesign 默认提供浅色/深色两套色板。主要核心逻辑是通过操作 html 标签的 theme-mode 属性触发样式切换,TDesign 组件库会自动监听该属性变化并应用对应主题样式。

二、实现步骤详解

具体步骤这里省略了搭建框架和项目中安装tdesign组件,主要详解明暗主题切换的具体代码和逻辑。

1.组件搭建

一般的明暗切换为一个太阳和一个月亮图标的切换,这里我们借用tdesign的icon和按钮来搭建组件

<template><div class="mode-btn-container"><t-button @click="toggleMode" class="mode-btn"><template #icon><ModeDarkIcon v-if="isDarkMode" /><ModeLightIcon v-else /></template></t-button></div>
</template><script setup>
import { ref } from 'vue'
const isDarkMode = ref(false)
const toggleMode = () => {}
</script><style lang="less" scoped>
.mode-btn-container {.mode-btn {margin-right: 0.5vw;}
}
</style>

2.状态持久化

使用 useStorage 组合式函数(通常来自 @vueuse/core 库),创建响应式状态 isDarkMode,值会持久化存储在 localStorage,键名为 'theme-mode',这也是tdesign组件中的主题,默认值为 false(初始为浅色模式),当值变化时会自动同步到本地存储,页面刷新后仍可保持状态

import { useStorage } from '@vueuse/core'
const isDarkMode = useStorage('theme-mode', false)

 3.模式切换逻辑

const toggleMode = () => {isDarkMode.value = !isDarkMode.value // 切换布尔值document.documentElement.setAttribute('theme-mode', isDarkMode.value ? 'dark' : 'light' // 更新HTML根元素属性)emit('toggleMode', isDarkMode.value) // 触发自定义事件
}

 4.组件挂载

初始化加载时同步主题状态(比如从localStorage恢复的持久化状),确保首次渲染时应用正确的主题样式

onMounted(() => {document.documentElement.setAttribute('theme-mode', isDarkMode.value ? 'dark' : 'light')
})

5.事件监听

监听isDarkMode响应式变量的变化,当主题状态变化时(通过切换操作),实时更新DOM属性,

watch(isDarkMode, newVal => {document.documentElement.setAttribute('theme-mode', newVal ? 'dark' : 'light')
})

 6.配置与优化

写完以上代码之后其实我们发现还未达到想要的想要,想要更好的使用还需要最后一步,也就是在使用:root选择器定义全局变量

//该代码依据项目进行修改,仅供参考
:root[theme-mode="light"] {--color-background: #009994;--color-title-background: #71b2b1;--color-chart-background: rgba(255, 255, 255, 0.7);--color-title-text: #282727;--color-manage-background: #fff;--color-dialog-txt:#282727;--color-background-img: url('@/assets/images/page/net-frame.gif') no-repeat;--color-detail-txt:#282727;--color-background-net:#009994;--color-txt-net:#fff;--color-station-background:#f2fffe;--bg-date-picker: #fff;--td-bg-color-secondarycontainer:#f3f3f3;--ele-hover-bg-color:#afe2f6;--ele-bg-color:#fff;:root[theme-mode="dark"] {--color-background: #02455f;--color-title-background: #116e93;--color-chart-background: #7c8d8d31;--color-title-text: #fff;--color-manage-background: #0F1014;--color-dialog-txt:#282727;--color-background-img: url('@/assets/images/page/net-frame-dark.gif') no-repeat;--color-detail-txt:#fff;--color-background-net:#fff;--color-txt-net:#282727;--color-station-background:none;--bg-date-picker: #fff;--td-bg-color-secondarycontainer:#c0bebe;--ele-hover-bg-color:#51a0be;--ele-bg-color:#242424;}

7.使用

具体使用方法对颜色使用 var() 函数引用变量,具体如下,假设我想要对这个切换的按钮实现明暗背景颜色的变化

 .mode-btn {background: var(--color-background);margin-right: 0.5vw;}

三、全部代码

<template><div class="mode-btn-container"><t-button @click="toggleMode" class="mode-btn"><template #icon><ModeDarkIcon v-if="isDarkMode" /><ModeLightIcon v-else /></template></t-button></div>
</template><script setup>
import { ref } from 'vue'
import { useStorage } from '@vueuse/core'
// 主题状态管理
const isDarkMode = useStorage('theme-mode', false)
const toggleMode = () => {isDarkMode.value = !isDarkMode.valuedocument.documentElement.setAttribute('theme-mode', isDarkMode.value ? 'dark' : 'light')emit('toggleMode', isDarkMode.value)
}
onMounted(() => {document.documentElement.setAttribute('theme-mode', isDarkMode.value ? 'dark' : 'light')
})
watch(isDarkMode, newVal => {document.documentElement.setAttribute('theme-mode', newVal ? 'dark' : 'light')
})
</script><style lang="less" scoped>
.mode-btn-container {.mode-btn {background: var(--color-background);margin-right: 0.5vw;}
}
</style>

全局css的文件,我这里是common.less

//该代码依据项目进行修改,仅供参考
:root[theme-mode="light"] {--color-background: #009994;--color-title-background: #71b2b1;--color-chart-background: rgba(255, 255, 255, 0.7);--color-title-text: #282727;--color-manage-background: #fff;--color-dialog-txt:#282727;--color-background-img: url('@/assets/images/page/net-frame.gif') no-repeat;--color-detail-txt:#282727;--color-background-net:#009994;--color-txt-net:#fff;--color-station-background:#f2fffe;--bg-date-picker: #fff;--td-bg-color-secondarycontainer:#f3f3f3;--ele-hover-bg-color:#afe2f6;--ele-bg-color:#fff;:root[theme-mode="dark"] {--color-background: #02455f;--color-title-background: #116e93;--color-chart-background: #7c8d8d31;--color-title-text: #fff;--color-manage-background: #0F1014;--color-dialog-txt:#282727;--color-background-img: url('@/assets/images/page/net-frame-dark.gif') no-repeat;--color-detail-txt:#fff;--color-background-net:#fff;--color-txt-net:#282727;--color-station-background:none;--bg-date-picker: #fff;--td-bg-color-secondarycontainer:#c0bebe;--ele-hover-bg-color:#51a0be;--ele-bg-color:#242424;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/86974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

goland 的 dug 设置

brew install delve # 或通过go install go install github.com/go-delve/delve/cmd/dlvlatestwhere dlvdlv.path/your/path/to/dlv环境变量 DEPLOY_MODEprivate;EGO_DEBUGtrue;EGO_MODEdev;MO_MODEdev;PD_MODEco;PRODUCT_MODEall

CVE-2020-1938源码分析与漏洞复现(Tomcat 文件包含/读取)

漏洞概述 漏洞名称&#xff1a;Tomcat AJP协议文件包含/读取漏洞&#xff08;Ghostcat&#xff09; CVE 编号&#xff1a;CVE-2020-1938 CVSS 评分&#xff1a;9.8 影响版本&#xff1a; Apache Tomcat 6.x (≤ 6.0.53)Apache Tomcat 7.x (≤ 7.0.99)Apache Tomcat 8.x (≤ 8…

基于51单片机的简易打铃系统

目录 具体实现功能 设计介绍 资料内容 全部内容 资料获取 具体实现功能 具体功能&#xff1a; &#xff08;1&#xff09;实时显示当前时间&#xff08;时、分、秒&#xff09;&#xff0c;LED模式指示灯亮&#xff1b;4个按键可以调整时间的时和分。 &#xff08;2&…

vue+cesium示例:3D热力图(附源码下载)

接到一位知识星友的邀请&#xff0c;随机模拟三维数据点&#xff0c;结合heatmap.js实现基于cesiumvue的3D热力图需求&#xff0c;适合学习Cesium与前端框架结合开发3D可视化项目。 demo源码运行环境以及配置 运行环境&#xff1a;依赖Node安装环境&#xff0c;demo本地Node版本…

批处理实现:自动抓取perfetto日志 自动导出到当前文件夹 自动打开分析页面

序言 最近在研究性能问题需要抓取trace文件。于是写了个脚本 使用 双击运行批处理文件&#xff0c;可以开始记录trace。而且以当前文件夹下面的。config.pbtx 作为配置文件。 &#xff08;pbtx就是一个json文件。配置了需要抓取那些参数&#xff0c;可以通过https://ui.per…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

​​Promise代码理解

1.事件循环与 Promise 执行顺序 案例 1&#xff1a;基础 Promise 同步异步区分 console.log(1); new Promise(resolve > {console.log(2);resolve();console.log(3); }).then(() > console.log(4)); console.log(5); 输出顺序&#xff1a;1&#xff0c;2&#xff0c;3…

57、原生组件注入-【源码分析】DispatcherServlet注入原理

57、原生组件注入DispatcherServlet注入原理 #### 继承关系 - DispatcherServlet继承自FrameworkServlet&#xff0c;而FrameworkServlet继承自HttpServletBean&#xff0c;最终HttpServletBean继承自HttpServlet。 - DispatcherServlet实现了ApplicationContextAware接口。 …

【动手学深度学习】3.5. 图像分类数据集

目录 3.5. 图像分类数据集1&#xff09;读取数据集2&#xff09;读取小批量3&#xff09;整合所有组件4&#xff09;小结 . 3.5. 图像分类数据集 我们将使用Fashion-MNIST数据集&#xff0c;作为图像分类数据集。 %matplotlib inline import torch import torchvision from …

Python的格式化输入输出

# Python 的格式化输出和格式化输入## 格式化输出Python 提供了多种字符串格式化的方法&#xff1a;### 1. % 格式化&#xff08;旧式格式化&#xff09;python name "Alice" age 25 print("Name: %s, Age: %d" % (name, age)) # 输出: Name: Alice, Age…

day65—回溯—单词搜索(LeetCode-79)

题目描述 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相…

iOS安全和逆向系列教程 第19篇:ARM64汇编语言基础与逆向分析

引言 在成功掌握iOS应用脱壳技术后,我们获得了可以进行静态分析的二进制文件。然而,要真正理解iOS应用的底层逻辑,我们必须深入到汇编语言层面。ARM64(也称为AArch64)是苹果在iPhone 5s及以后设备中使用的指令集架构。本篇文章将深入探讨ARM64汇编语言的基础知识,并结合…

使用Gitlab CI/CD结合docker容器实现自动化部署

Gitlab CI/CD基本介绍 核心概念 持续集成&#xff08;CI&#xff09;&#xff1a;每次代码提交后自动触发构建、测试和代码检查&#xff0c;确保代码质量 持续交付/部署&#xff08;CD&#xff09;&#xff1a;在 CI 基础上自动将代码部署到测试或生产环境&#xff0c;支持人工…

初学者运行Pycharm程序可能会出现的问题,及解决办法

文章目录 前言一、ModuleNotFoundError: No module named sklearn二、ImportError: cannot import name show_config from numpy (unknown location)三、Pycharm报错&#xff1a;“Original error was: DLL load failed: 找不到指定的模块“ 的解决办法四、ImportError: cannot…

Android开发中的Java与Kotlin:全面对比与深度解析

Android开发中的Java与Kotlin&#xff1a;全面对比与深度解析 在Android开发领域&#xff0c;Java和Kotlin是两种主流编程语言。自Google在2017年宣布Kotlin为Android官方支持语言以来&#xff0c;Kotlin凭借其现代语法特性和与Java的无缝兼容性&#xff0c;逐渐成为开发者的新…

为应对激烈竞争环境,IBMS系统如何提升企业管理效率

IBMS智能管理系统&#xff1a;赋能企业高效运营&#xff0c;决胜竞争新时代 在瞬息万变的商业环境中&#xff0c;效率就是竞争力&#xff01;企业如何快速响应市场变化、优化内部流程、降低成本并实现精准决策&#xff1f;IBMS智能管理系统以创新科技为引擎&#xff0c;为企业…

2.3 ASPICE的架构与设计

在ASPICE中&#xff0c;架构与设计是汽车软件开发过程中非常重要的一环&#xff0c;它涉及到定义和设计软件系统的整体结构、组件以及其相互关系。良好的架构与设计可以帮助团队更好地理解和管理软件系统&#xff0c;提高系统的可维护性、可扩展性和性能。以下是ASPICE中架构与…

生益PCB耐高温PCB板材怎么样?

在5G基站昼夜不停地吞吐数据时&#xff0c;在新能源汽车电池管理系统经受极寒酷暑考验时&#xff0c;在航空航天器穿越大气层承受2000℃热浪冲击时&#xff0c;一块优质PCB板材的“抗热基因”正在决定着整个系统的生死存亡。生益科技研发的耐高温PCB板材&#xff0c;正是在这场…

Java Spring ApplicationEvent 概述

一、Spring 事件机制核心概念 1. 事件驱动架构模型 发布-订阅模式&#xff1a;解耦事件生产者和消费者观察者模式&#xff1a;监听器监听特定事件事件驱动优势&#xff1a; 组件间松耦合系统扩展性好支持异步处理事件溯源支持 2. 核心组件 组件作用实现方式ApplicationEve…

Spring核心框架完全指南 - 基础知识全解析

📖 目录 🌟 Spring框架简介 🏗️ IoC容器详解 💉 依赖注入(DI)深入理解 ⚙️ Bean配置与管理 🎯 Bean的作用域 🔄 Bean生命周期 🎭 面向切面编程(AOP) 📝 Spring注解详解 📁 资源管理 📢 事件机制 🔤 SpEL表达式语言 🎯 实战案例 📚 总…