当前位置: 首页 > news >正文

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;}

相关文章:

  • 6.10 Mysql 事务 锁 面试题
  • C++_核心编程_多态案例二-制作饮品
  • 赛尔发布SHARE 5系列航测相机,外业更高效,建模更优质
  • 制作一款打飞机游戏69:编辑器升级
  • AliExpress(速卖通)铺货工具,图片下载,SKU浏览,详情搬运,使用方法
  • 3分钟配置好nacos集群(docker compose)
  • Docker 创建及部署完整流程
  • (五)docker环境中配置hosts
  • 【论文阅读笔记】HaDes幻觉检测benchmark
  • 搭建gitlab ci/cd runner实现对c++项目的自动编译和打包
  • 丝杆升降机的物联网与大数据应用的具体例子
  • V837s-SDK Telnetd服务连接不上异常解决
  • A16 扁平化管理
  • YSYX学习记录(八)
  • PHP 多种内置的验证规则和函数
  • 网络验证Api用户系统(本系统基于php+mysql开发) 软件验证卡密系统 源码测试搭建成功
  • MFC 第一章概述
  • RabbitMQ的使用--Spring AMQP(更新中)
  • ubuntu24安装TensorRT
  • Vue.js 中的 v-bind 指令详解
  • 做网站视频博彩/网络优化大师app
  • 手机网站制作代理商/seo优化的主要内容
  • 菠菜建设网站/网络营销产品策略分析
  • 网络工程师证/关键词排名优化怎么样
  • 赣榆哪里有做网站的/百度风云榜官网
  • 网站幻灯片效果代码/百度收录提交入口地址