vue3 主题模式 结合 element-plus的主题

vue3 主题模式 结合 element-plus的主题

 npm i element-plus --save-dev

在 Vue 3 中,实现主题模式主要有以下几种方式

1.使用 CSS 变量(自定义属性)
  • CSS 变量是一种在 CSS 中定义可重用值的方式。在主题模式中,可以将颜色、字体大小等样式属性设置为 CSS 变量。然后通过 JavaScript 或 Vue 的响应式特性来切换这些变量的值,从而实现主题的切换
var.css
:root {--login-bg-color: #293146;  --left-menu-max-width: 200px;--left-menu-min-width: 64px;--left-menu-bg-color: #001529;--left-menu-bg-light-color: #0f2438;--left-menu-bg-active-color: var(--el-color-primary);--left-menu-text-color: #bfcbd9;--left-menu-text-active-color: #fff;--left-menu-collapse-bg-active-color: var(--el-color-primary);--logo-height: 50px;--logo-title-text-color: #fff;--top-header-bg-color: '#fff';--top-header-text-color: 'inherit';--top-header-hover-color: #f6f6f6;--top-tool-height: var(--logo-height);  --top-tool-p-x: 0;--tags-view-height: 35px;--tab-menu-max-width: 80px;--tab-menu-min-width: 30px;--tab-menu-collapse-height: 36px;   }.dark {--app-content-bg-color: var(--el-bg-color);}html,body {-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}*,:after,:before {margin: 0;padding: 0;box-sizing: border-box;}
index.scss
@use './var.css';
@use 'element-plus/theme-chalk/dark/css-vars.css';
2.在main 引入 index.scss
// 引入全局样式
import '@/styles/index.scss'
3.在 Vue 组件中动态切换主题
<script setup lang="ts">
import { useAppStore } from '@/store/modules/app' //引入的状态管理
import { ThemeSwitch } from '@/components/ThemeSwitch' // 引入的组件黑白切换const appStore =  useAppStore()
const textColor = computed(() => appStore.getTextColor)
appStore.initTheme() // Pinia 实现状态管理 </script><template><!--element-plus ElConfigProvider 组件的的封装--><ConfigGlobal><!-- <p style="color: var(--el-text-color-primary);">p标签</p> --><p :style="{'color':textColor}"  >p标签</p><ThemeSwitch></ThemeSwitch></ConfigGlobal></template><style scoped lang="scss">
$prefix-cls: #{$namespace}-app;.size {width: 100%;height: 100%;
}html,
body {@extend .size;padding: 0 !important;margin: 0;overflow: hidden;#app {@extend .size;}
}.#{$prefix-cls}-grey-mode {filter: grayscale(100%);
}</style>

注意:CSS 变量与样式冲突解决

  • 如果你自定义的主题与 Element Plus 的默认样式冲突,可以通过在你的主题 CSS 文件中明确覆盖 Element Plus 的变量来解决。
  • 在 var.css 中,确保所有需要覆盖的变量都被正确设置
  • element-plus 在vite.config.ts 配置自动导入

store/modules/app.ts

import { defineStore } from "pinia";
// import { store } from '../index'
// import { colorIsDark, hexToRGB, lighten, mix } from '@/utils/color'
import { setCssVar,humpToUnderline } from '@/utils'
import { useDark } from '@vueuse/core'  安装 @vueuse/coreexport const useAppStore  = defineStore('app', {state: () => {return {isCollapse: false, // 菜单是否折叠isFullScreen: false, // 页面是否全屏isDark:false, // 是否是暗黑模式textColor: '#303133',theme:{//文字的颜色// 主题色elColorPrimary: '#409eff',// 左侧菜单边框颜色leftMenuBorderColor: 'inherit',// 左侧菜单背景颜色leftMenuBgColor: '#001529',// 左侧菜单浅色背景颜色leftMenuBgLightColor: '#0f2438',// 左侧菜单选中背景颜色leftMenuBgActiveColor: 'var(--el-color-primary)',// 左侧菜单收起选中背景颜色leftMenuCollapseBgActiveColor: 'var(--el-color-primary)',// 左侧菜单字体颜色leftMenuTextColor: '#bfcbd9',// 左侧菜单选中字体颜色leftMenuTextActiveColor: '#fff',// logo字体颜色logoTitleTextColor: '#fff',// logo边框颜色logoBorderColor: 'inherit',// 头部背景颜色topHeaderBgColor: '#fff',// 头部字体颜色topHeaderTextColor: 'inherit',// 头部悬停颜色topHeaderHoverColor: '#f6f6f6',// 头部边框颜色topToolBorderColor: '#eee'}} },getters:{getIsDark(): boolean {return this.isDark},getTextColor(): string {return this.textColor}},actions: {setIsDark(isDark: boolean) {this.isDark = isDarkif (this.isDark) {//  setCssVar('--el-text-color-primary', 'red')document.documentElement.classList.add('dark')document.documentElement.classList.remove('light')} else {//   setCssVar('--el-text-color-primary', '#303133')document.documentElement.classList.add('light')document.documentElement.classList.remove('dark')}this.textColor = this.isDark? 'red' : '#303133'// wsCache.set(CACHE_KEY.IS_DARK, this.isDark)},  setCssVarTheme() {for (const key in this.theme) {setCssVar(`--${humpToUnderline(key)}`, this.theme[key])}// this.setPrimaryLight()},setPrimaryLight() {if (this.theme.elColorPrimary) {const elColorPrimary = this.theme.elColorPrimaryconst color = this.isDark ? '#000000' : '#ffffff'const lightList = [3, 5, 7, 8, 9]lightList.forEach((v) => {setCssVar(`--el-color-primary-light-${v}`, mix(color, elColorPrimary, v / 10))})setCssVar(`--el-color-primary-dark-2`, mix(color, elColorPrimary, 0.2))}},initTheme() {const isDark = useDark({valueDark: 'dark',valueLight: 'light'})isDark.value = this.getIsDark},},persist: true
})// export const useAppStoreWithOut = () => {
//    return useAppStore(store)
//  }
// 使用到的函数
export const setCssVar = (prop: string, val: any, dom = document.documentElement) => {dom.style.setProperty(prop, val)
}/*** @param str 需要转下划线的驼峰字符串* @returns 字符串下划线*/
export const humpToUnderline = (str: string): string => {return str.replace(/([A-Z])/g, '-$1').toLowerCase()
}

themeSwitch.vue

<script lang="ts" setup>
import { useAppStore } from '@/store/modules/app'
import { useIcon } from '@/hooks/web/useIcon'
import { useDesign } from '@/hooks/web/useDesign'
defineOptions({ name: 'ThemeSwitch' })const { getPrefixCls } = useDesign()// const prefixCls = getPrefixCls('theme-switch')
const prePrefixCls = 'ad-theme-switch'
const Sun = useIcon({ icon: 'emojione-monotone:sun', color: '#fde047' })const CrescentMoon = useIcon({ icon: 'emojione-monotone:crescent-moon', color: '#fde047' })const appStore = useAppStore()// 初始化获取是否是暗黑主题
// const isDark = ref(appStore.getIsDark)// 设置switch的背景颜色
const blackColor = 'var(--el-color-black)'// const themeChange = (val: boolean) => {
//   appStore.setIsDark(val)
// }
const isDark = computed({get() {return appStore.getIsDark},set(val: boolean) {appStore.setIsDark(val)}
})
</script><template><el-switchv-model="isDark":active-color="blackColor":active-icon="Sun":border-color="blackColor":class="prefixCls":inactive-color="blackColor":inactive-icon="CrescentMoon"inline-prompt/>
</template>
<style lang="scss" scoped>
:deep(.el-switch__core .el-switch__inner .is-icon) {overflow: visible;
}
</style>

初始化的主题 ConfigGlobal.vue

<script setup lang="ts">
import { ElConfigProvider } from 'element-plus'
import { useAppStore } from '@/store/modules/app'
import { useDesign } from '@/hooks/web/useDesign'const { variables } = useDesign() // 命名规则const appStore = useAppStore()// 初始化所有主题色
onMounted(() => {appStore.setCssVarTheme()
})</script><template><ElConfigProvider:namespace="variables.elNamespace":message="{ max: 1 }"><slot></slot></ElConfigProvider>
</template>

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

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

相关文章

科大讯飞Q1营收46.6亿同比增长27.7%,扣非净利同比增长48.3%

4月21日盘后&#xff0c;AI龙头科大讯飞&#xff08;002230.SZ&#xff09;发布2024年报&#xff0c;公司全年实现营业收入233.43亿元&#xff0c;同比增长18.79%&#xff0c;同期归母净利润为5.6亿元。 公司核心赛道业务保持快速增长&#xff0c;消费者、教育、汽车、医疗业务…

Day5-UFS总结

UFS 传输协议的本质&#xff1a;两个收发器件&#xff0c;对需要传输的数据&#xff0c;一层一层的封装和解析&#xff0c;利用封装增加的额外信息&#xff0c;做一些数据处理&#xff0c;完成源地址到目标地址的数据传输功能。 应用协议的本质&#xff1a;基于某种传输协议之…

嵌入式工程师( C / C++ )笔试面试题汇总

注&#xff1a;本文为 “嵌入式工程师笔试面试题” 相关文章合辑。 未整理去重。 如有内容异常&#xff0c;请看原文。 嵌入式必会 C 语言笔试题汇总 Z 沉浮 嵌入式之旅 2021 年 01 月 19 日 00:00 用预处理指令 #define 声明一个常数&#xff0c;用以表明 1 年中有多少秒&a…

29-JavaScript基础语法(函数)

知识目标 理解函数的基本概念&#xff1b;掌握函数的定义和调用&#xff1b;理解函数参数和返回值及作用域&#xff1b;掌握函数高阶用法。 1. 理解函数的基本概念 明确函数在 JavaScript 里是一段可重复使用的代码块&#xff0c;它能接收输入参数&#xff0c;执行特定任务&…

AI答题pk机器人来袭

AI答题PK机器人是一种具备知识问答竞赛功能的人工智能程序。以下为您详细介绍&#xff1a; 一、实时对战&#xff1a;能在答题排位PK升级赛中&#xff0c;与用户进行1V1在线实时PK答题 。比如在一些知识竞赛类APP中&#xff0c;用户可匹配到AI机器人对手&#xff0c;在规定时…

PclSharp ——pcl的c#nuget包

简介&#xff1a; NuGet Gallery | PclSharp 1.8.1.20180820-beta07 下载.NET Framework 4.5.2 Developer Pack&#xff1a; 下载 .NET Framework 4.5.2 Developer Pack Offline Installer 离线安装nupkg&#xff1a; nupkg是visual studio 的NuGet Package的一个包文件 安…

【Unity笔记】Unity音视频播放监听器封装笔记:VideoPlayer + AudioSource事件触发与编辑器扩展

关键点 Unity VideoPlayer 播放结束事件Unity AudioSource 播放检测 Unity音视频播放监听器封装笔记&#xff1a;VideoPlayer AudioSource事件触发与编辑器扩展 在 Unity 的多媒体开发中&#xff0c;我们经常需要监听 VideoPlayer 或 AudioSource 的播放状态&#xff0c;以便…

WPF常用技巧汇总

主要用于记录工作中发现的一些问题和常见的解决方法。 此文会持续更新。 >abp new Evan.MyWpfApp -t wpf --old --framework .net8 1. 解决不同屏幕分辨率下的锯齿问题 UseLayoutRounding"True" <Grid UseLayoutRounding"True"><Border Mar…

分数线降低,25西电马克思主义学院(考研录取情况)

1、马克思主义学院各个方向 2、马克思主义学院近三年复试分数线对比 学长、学姐分析 由表可看出&#xff1a; 1、马克思主义理论25年相较于24年下降10分&#xff0c;为355分 3、25vs24推免/统招人数对比 学长、学姐分析 由表可看出&#xff1a; 1、 马克思主义学院25年共接…

【Linux网络】构建UDP服务器与字典翻译系统

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…

【项目管理】成本类计算 笔记

项目管理-相关文档&#xff0c;希望互相学习&#xff0c;共同进步 风123456789&#xff5e;-CSDN博客 &#xff08;一&#xff09;知识总览 项目管理知识域 知识点&#xff1a; &#xff08;项目管理概论、立项管理、十大知识域、配置与变更管理、绩效域&#xff09; 对应&…

div(HTML标准元素)和view(微信小程序专用组件)的主要区别体

div&#xff08;HTML标准元素&#xff09;和view&#xff08;微信小程序专用组件&#xff09;的主要区别体现在以下方面&#xff1a; 一、应用场景与开发框架 ‌适用平台不同‌ div是HTML/CSS开发中通用的块级元素&#xff0c;用于Web页面布局‌&#xff1b;view是微信小程序专…

【C++软件实战问题排查经验分享】UI界面卡顿 | CPU占用高 | GDI对象泄漏 | 线程堵塞 系列问题排查总结

目录 1、UI界面卡顿问题排查 2、软件CPU占用高问题排查 3、UI界面显示异常&#xff08;GDI对象泄漏导致窗口绘制异常&#xff09;问题排查 4、软件线程堵塞&#xff08;包含线程死锁&#xff09;问题排查 5、最后 C软件异常排查从入门到精通系列教程&#xff08;核心精品专…

管理杂谈——采石矶大捷的传奇与启示

南宋抗金史上&#xff0c;岳飞与岳家军的铁血传奇家喻户晓&#xff0c;但另一位力挽狂澜的“文官战神”却常被忽视——他从未掌兵&#xff0c;却在南宋存亡之际整合溃军&#xff0c;以少胜多&#xff0c;缔造采石矶大捷。此人正是虞允文。一介书生何以扭转乾坤&#xff1f;他的…

动态规划-零钱兑换

332.零钱兑换 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。你可以认为每种硬币的数量是无…

SpringAI+DeepSeek大模型应用开发——4 对话机器人

目录​​​​​​​ ​​​​​​​​​​​​​​项目初始化 pom文件 配置模型 ChatClient 同步调用 流式调用 日志功能 对接前端 解决跨域 会话记忆功能 ChatMemory 添加会话记忆功能 会话历史 管理会话id 保存会话id 查询会话历史 完善会话记忆 定义可序列…

Java 关键字

本章列出了Java 语言的所有关键字和“类关键字的单词”。 “受限关键字”是指&#xff0c;它们旨在模块声明中是关键字&#xff0c;在其他情况下则是标识符。 “受限标识符”是指&#xff0c;除非用在某些特定位置&#xff0c;否则他们只是标识符。例如&#xff0c;var一般都…

AI重塑网络安全:机遇与威胁并存的“双刃剑”时代

一、引言 人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;正在深刻改变网络安全行业的格局。从ChatGPT生成钓鱼邮件到AI驱动的漏洞挖掘&#xff0c;从零信任架构的普及到安全大模型的实战应用&#xff0c;AI既是攻击者的“新武器”&#xff0c;也是防御者的“新…

网络原理——UDP

1、 与TCP的关键区别 特性UDPTCP连接方式无连接面向连接可靠性不可靠可靠数据顺序不保证顺序保证顺序传输速度更快相对较慢头部开销8字节20-60字节流量控制无有拥塞控制无有适用场景实时应用、广播/多播可靠性要求高的应用 2、UDP 报文结构 报文结构大致可以分为首部和载荷&a…

STM32——新建工程并使用寄存器以及库函数进行点灯

本文是根据江协科技提供的教学视频所写&#xff0c;旨在便于日后复习&#xff0c;同时供学习嵌入式的朋友们参考&#xff0c;文中涉及到的所有资料也均来源于江协科技&#xff08;资料下载&#xff09;。 新建工程并使用寄存器以及库函数进行点灯操作 新建工程步骤1.建立工程2.…