从零开始Vue3+Element Plus后台管理系统(17)——一键换肤的N种方案

article/2025/7/12 11:47:11

暗黑模式

基于Element Plus和Tailwind CSS灵活的设计,我们很容易在项目中实现暗黑模式,具体可以参考之前的文章《从零开始写一个Vue3+Element Plus的后台管理系统(二)——Layout页面布局的实现》

换肤方案

如果需要给用户提供更多主题,更丰富的皮肤,就得自己来开发换肤功能了。

换肤的方式由易到难大概分为3种:

  1. 简单换肤,提供N种配色方案供用户选择,一般只对配色进行切换,比如禅道,它提供了蓝色、粉色、绿色等方案;
  2. 个性化定制,可以自己定制主要颜色、阴影、边框等样式,个性化更强;
  3. 整站模板,提供N个风格迥异的模版布局和UI界面,彻底改头换面。

技术实现

以下仅针对使用Element Plus 的项目中进行换肤。

CSS变量

在开始之前,需要先了解CSS变量,它是一个非常有用的功能,几乎所有浏览器都支持,除了IE。既然选择了Vue3,明摆着就不想支持IE,所以我们可以愉快的使用CSS变量。

Element Plus 提取并整理了所有的设计变量,并通过 CSS Vars 技术实现动态更新主题。在我们的项目中找到node_modules/element-plus/theme-chalk,查看其中的CSS文件,可以看到其中有各种组件用到的CSS变量的定义。我把index.css拿出来格式化并存档,方便日后参考使用。

格式化以后的文件有140多行,截取部分贴出来:

:root {--el-color-white: #ffffff;--el-color-black: #000000;--el-color-primary-rgb: 64, 158, 255;--el-color-success-rgb: 103, 194, 58;--el-color-warning-rgb: 230, 162, 60;...
}:root {color-scheme: light;--el-color-white: #ffffff;--el-color-black: #000000;--el-color-primary: #409eff;...
}

在f12控制台,或者查看单个组件的样式文件,可以看到Element Plus通过CSS变量来设置组件的样式。

image.png

image.png

继续研究Element Plus的包,可以找到这个文件node_modules/element-plus/theme-chalk/src/var.scss,它保存的是SCSS变量,最终生成了theme-chalk/index.css

如果只修改Element主题而不考虑动态换肤,我们可以通过修改SCSS变量定制自己的ep外观。但动态换肤就需要使用CSS变量来完成。

OK,讲了这么多,其实就是为使用CSS变量换肤做铺垫。

简单换肤的技术实现

项目开发过程中,在<style>中自定义样式,我会尽量使用EP的CSS变量,一是可以直接利用EP的dark模式,二是为将来换肤做准备。比如页面头部:

<style scoped lang="scss">
.v-header {...border-bottom: 1px solid var(--el-border-color);.logo {color: var(--el-color-primary);}
}
</style>

修改css变量

由此可以想到,在我们需要更换主题样式时,只需动态修改CSS变量即可。

// 修改 EP 主要颜色为 红色
document.documentElement.style.setProperty('--el-color-primary', 'red')

建立配色方案的CSS变量

当我们需要修改的变量数量很少时,一个个修改还好,属性多的话这种做法显然不够优雅。那么暗黑模式是如何实现一键切换样式的呢?

dark模式是通过在html标签增加.dark,同时新建了一份专属dark的CSS Vars。同理,只需给不同的主题设置不同的CSS Vars,然后动态修改html的class,就可以实现简单换肤。

document.getElementsByTagName('html')[0].className = theme

在assets/css中新建theme.css

.red {--el-color-primary: #ff2551;
}.pink {--el-color-primary: #f47983;
}.green {--el-color-primary: #0c8918;
}.brown {--el-color-primary: #ae7000;
}.grape {--el-color-primary: #725e82;
}

切换主题操作 ThemeSetting.vue,通过切换html的classname使用不同主题下的CSS Vars

const themes = [{ name: 'red', color: '#ff2551' },{ name: 'pink', color: '#f47983' },{ name: 'green', color: '#0c8918' },{ name: 'brown', color: '#ae7000' },{ name: 'grape', color: '#725e82' }
]function changeColor(theme: string) {document.getElementsByTagName('html')[0].className = theme
}

2.gif
到此为止,一个最简单的换肤功能已经出来了,后续可以在theme.css中增加更多的变量来实现更多样式的变化(变量名根据按照上面拿到的Element Plus的CSS变量即可),通过这个操作已经可以实现禅道系统的换肤功能需求。

主题持久化

还有一个小问题,那就是当我们刷新页面后,主题回到了页面最初的样子,看来又需要做状态的持久化喽,这已经是老生常谈了。照旧使用pinia加persist。

store/theme.ts

import { defineStore } from 'pinia'
import { ref } from 'vue'export const useThemeStore = defineStore('theme',() => {let scheme = ref('')// 设置配色主题function setScheme(str: string) {scheme.value = str}return { scheme, setCSS }},{persist: true}
)

修改换肤方法,把主题名称保存到状态管理中。

function changeColor(theme: string) {document.getElementsByTagName('html')[0].className = themeuseTheme.scheme = theme
}

layout下新建theme/index.ts 用于初始化主题,然后在main.ts调用

import { Pinia } from 'pinia'
import { useThemeStore } from '~/store/theme'export default (pinia: Pinia) => {const useTheme = useThemeStore(pinia)// const el = document.documentElementif (useTheme.scheme) {document.getElementsByTagName('html')[0].className = useTheme.scheme}
}

main.ts

// theme
import initTheme from '~/layout/theme'
initTheme(pinia)

OK,现在再刷新页面,也不会丢失主题状态了,打开控制台可以看到,我们选择主题已经保存在localStorage中,只有清除缓存,才会回到默认的主题。

image.png

写完最简单的方案,已经傍晚了,先休息一下吧。

方案二,个性化自定义

如果你用过Element UI,应该知道它提供了一个自定义主题功能,下载后即可使用。

方案二的思路和它类似,用户可以自己定义color,menu,border等一些常用值,然后保存为自己的主题方案

image.png

未完待续

项目地址

本项目GIT地址:https://github.com/lucidity99/mocha-vue3-system

如果有帮助,给个star ✨ 点个赞👍


http://chatgpt.dhexx.cn/article/pQQcRZjo.shtml

相关文章

三步实现Android应用内一键换肤,无需重启应用,无需编写多余代码

古人学问无遗力&#xff0c;少壮工夫老始成。 纸上得来终觉浅&#xff0c;绝知此事要躬行。 --《冬夜读书示子聿》 陆游 换肤效果演示 四种皮肤切换&#xff1a;默认白色、蓝色、绿色和玫瑰红&#xff1a; 前言 先给大家介绍一下现在比较主流的、Star比较多的换肤框架&#…

前端 “一键换肤“ 的 N 种方案

前端瓶子君&#xff0c;关注公众号 回复算法&#xff0c;加入前端编程面试算法每日一题群 前言 现在越来越多的网站都提供了拥有换肤&#xff08;切换主题&#xff09;功能&#xff0c;如 ElementUI[2]&#xff0c;既是为了迎合用户需求&#xff0c;或是为了凸显自己特点&#…

Python装逼指南——五行代码实现批量抠图

你是否曾经想将某张照片中的人物抠出来&#xff0c;然后拼接到其他图片上去&#xff0c;从而可以即使你在天涯海角&#xff0c;我也可以到此一游&#xff1f; 专业点的人使用 PhotoShop 的“魔棒”工具可以抠图&#xff0c;非专业人士可以使用各种美图 APP 来实现&#xff0c;但…

iter()函数联队*、zip()实现序列“定长”拆分——基于iterator特性拆解繁复的单行“装逼代码”,搞明白序列定长拆分“秘法”

Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么简单…… My CSDN主页、My HOT博、My Python 学习个人备忘录好文力荐、 老齐教室 自学并不是什么神秘的东西&#xff0c;一个人一…

如何在你朋友面前装逼4(程序代码)

大家好&#xff0c;我是不讲武德。今天我来教大家在电脑上画画&#xff0c;非常简单 --------------------------------------------------------------------------------------------------------------------- 第一步&#xff1a;新建一个文本文档 第二步&#xff1a;打开…

dtree树形菜单带搜索复选框单选框插件

dtree树形菜单带搜索复选框单选框插件 用于选择部门或者选择部门下人员 效果如下图 dtree树形菜单带搜索不带单选框复选框 dtree选择部门或者选择部门下人员复选框单选框插件 带搜索 https://download.csdn.net/download/qq_27559331/9885259

OA与帆软BI跨系统用户、部门、岗位同步总结

目录 前言&#xff1a; 一、初衷 1、需要准备啥&#xff1f; 2、同步接口或者数据集 3、建立服务器数据集 代码&#xff1a; 效果&#xff1a; 二、正式同步 1、建立服务器数据集 2、建立服务器树状数据集 3、选择对应关系进行同步 4、等待与设置同步频率 5、注意事项 …

JAVA 对接钉钉API(人员、部门、官方智能工作流)20210527

前言 应公司要求&#xff0c;公司人事HR系统需要对接钉钉考勤数据&#xff0c;所以需要获取钉钉的打卡记录、出差、外出、请假、调岗的数据&#xff0c;然后转换成HR系统数据。 对接前准备 创建应用 1、首先需要管理员登录钉钉开放平台&#xff0c;创建应用。 说明 只有管理…

Element使用级联选择器

Element使用级联选择器 element的级联选择器和select不一样,下拉框我们可以手动定义label和value,只需要将查出来的值循环一下即可 但是级联选择器的视图层是这样的 只有 :options=“options” 这个属性让我们绑定值,没办法绑定他的label和value element官网给的数据结构是这…

研发部的人员素质要求及自我培养

IT行业发展已经走的很远了&#xff0c;纵观世界经济的发展&#xff0c;经济全球化进程明显加快&#xff0c;信息化已成为全球化的迫切需要和必要保证。世界范围的产业结构调整和信息技术进步&#xff0c;必将对中国信息产业的发展产生深刻影响&#xff0c;所以IT行业的前景还是…

2-Springboot集成Flowable之 选择人员的界面自定义开发

目录 效果实现思路1、新建自己的 my-assignment-popup.html2、修改properties-assignment-controller.js 效果 演示地址 代码地址 前端代码地址 实现思路 部门是基于bootstrap-treeview插件实现的&#xff0c;表格是自己用div css写的。其实自己了解angular修改这里应该没有…

用户选择框设计思路

最近新项目要用到选择人员&#xff0c;于是重新在新项目中设计了一版选人框。 效果图如下&#xff1a; 功能部分 一个选人框主要有以下几个展示部分&#xff1a; 人员组织树已选节点信息操作工具栏 这三大部分再细分下各自应有的基础功能&#xff1a; 人员展示部分&…

解读华为的流程与 IT 管理部门

公众号回复&#xff1a;干货&#xff0c;领取价值58元/套IT管理体系文档 公众号回复&#xff1a;ITIL教材&#xff0c;领取最新ITIL4中文教材 更多专业文档请访问 www.itilzj.com 华为&#xff0c;其流程与IT管理部是国内IT部门的发展标杆&#xff0c;负责的是华为各个部门和跨…

人员选择树,搜索自动筛选功能

要实现的功能截图&#xff1a; 要求&#xff1a; 1、点击收件人输入框可以根据拼音自动筛选数据&#xff0c;并且标记已经选择的数据&#xff0c;没有结果的时候提示&#xff0c;相应的更新左边树节点状态 2、勾选树右侧树的节点左侧输入框出现一一对应的节点名称 用到的…

级联选择器el-cascader处理复杂数据(四层、五层数据),回显部门以及部门下的人员

注意&#xff1a;参考第五层的数据处理比较nice 当级联选择器需要绑定的数组不再是简易数据&#xff0c;props涉及的字段不再是一个&#xff0c;而是列表里面套列表 比如&#xff0c;我想要获取部门以及下面的员工&#xff0c;如何显示&#xff1f;如下图1所示&#xff0c;后…

一个简单的联系人及组织架构选择人员的实现

前言&#xff1a;技术实现&#xff1a;Vitevue3tsvant。 本次主要是因为本人说了一个类似的功能&#xff0c;前期遇到了很多坑&#xff0c;导致 进度缓慢。虽然可以实现&#xff0c;但是都基于多个数组操作的情况&#xff0c;当涉及功能修改或优化&#xff0c;就很难实现了。 本…

jQuery仿钉钉组织架构的选择部门功能,移动端完美树形图

在网上找了好久&#xff0c;实在没见到有类似的只能自己写一个一、功能如图所示&#xff0c;点击选择无限下级功能 二、css <style>body{margin:0;padding:0;background:#ffffff}.spaceBetween {display: flex;justify-content: space-between;align-items: center;}.su…

vue的el-tree实现部门人员的tree展示选择,包括根据已有id进行默认选中设置

根据部门和人员&#xff0c;生成部门人员选择树&#xff0c;用的是Vue的el-tree生产树。 java部分------------------------------------------------------------------------------- 1&#xff1a;中间实体dto&#xff08;就是前端要的字段&#xff0c;让从数据库中查询的时…

Java+zTree审批人员选择

实现一个类似于钉钉审批人员选择的功能。 这里使用zTree实现组织架构树。 实体类需要有id,pId实现上下级关系。 company.java getter/setter略。 private int company_id;//公司idprivate String company_name;//公司名称private String remark;//备注信息private String f…