记录--前端换肤方案 - element+less无感换肤(无需页面刷新)
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
前端换肤方案 - element+less无感换肤(无需页面刷新)
前言
前不久在改造一个迭代了一年多的项目时,增加了一个换肤功能。通过自己的探索,总结出了一套比较合适的改造方案供大家参考,如有更好的方案欢迎评论区踊跃评论
先上效果:

聊聊现有方案
在查阅现有方案时,总结了目前使用的几种方案:
1、定义多套样式
首先定义一套或多套样式变量,包括浅色和深色两种主题。在scss或less中使用变量,通过js改变root节点的class或属性来达到样式覆盖。 这种方式实现的前端换肤方案,可能会导致样式不易管理,查找样式复杂,每一套皮肤需要写一个css文件,造成多个css代码冗余。
$dark-fill-1: #222;
$dark-color-text: #fff;
$dark-color-text-1: rgba(255,255,255,0.3);
$dark-color-text-2: $color-brand1; [data-theme="dark"] {
body { background: $dark-fill-1; }
.item .name { color: $dark-color-text; }
.item .desc { color: $dark-color-text-1; }
.header .text { color: $dark-color-text-2; }
}
2、使用less传参
通过less或scss的传参属性,同样的只要改变根节点class或属性即可以改变页面样式,与第一点的优点是不需要写多份css文件,缺点是通过方法传入,当样式过多时,参数过多,需要改变某一个颜色成本高,容易造成问题。
.theme(
@mainPageBG: #f4f6ff,
@fColor: #1b1e29,
@vanBgColor: rgb(198, 183, 140),
@vanColor: #fff
) {
.home {
background: @mainPageBG;
color: @fColor;
}
} .themeWhite {
.theme(#fff, #1b1e29, rgb(198, 183, 140), #fff);
}
.themeBlack {
.theme(#090c14, #fff, rgb(198, 183, 140), #fff);
}
3、VueUse+css变量快速切换
使用外部库VueUse的useDark快速切换黑暗和明亮模式。
<script setup lang="ts">
import { useToggle } from '@vueuse/shared'
import { isDark } from '../../.vitepress/theme/composables/dark' // const isDark = useDark()
const toggleDark = useToggle(isDark)
</script> <template>
<button @click="toggleDark()">
<i inline-block align-middle i="dark:carbon-moon carbon-sun" /> <span class="ml-2">{{ isDark ? 'Dark' : 'Light' }}</span>
</button>
</template>
最终解决方案
接触了解了上述几个方案后,结合项目本身架构(less+element+echarts+map),最终采用了以下使用方案。
less变量处理
1、定义不同肤色的css变量
.themeDark {
--theme-color: #141414;
--header-primary-color: #1a3750;
--bg-content-default: #1a3750;
--bg-theme-default: #13293b;
--bg-left-color: #27415a;
}
.themeLight {
--theme-color: #f4f4f4;
--header-primary-color: #2670ff;
--bg-content-default: #fff;
--bg-theme-default: #f3f5f9;
--bg-left-color: #eff3f4;
}
2、引入css变量,并通过定义less变量使用,解决了通过方法传参,参数过多的问题。
//换肤相关
@import './dark.less';
@import './light.less'; @theme-color: var(--theme-color-te);
@header-primary-color: var(--header-primary-color);
@bg-content-default: var(--bg-content-default);
@bg-left-color: var(--bg-left-color);
@bg-theme-default: var(--bg-theme-default);
@font-default-color: var(--font-default-color);
element 主题切换
1、可以在element官网定制和下载不同主题的style文件,将css文件更名为less,在最外层增加自定义的类。
.themeDark{
//下载的css文件
...
}
2、为了开发中不用每次去编译这个较大的less文件,再通过less命令,将less转为css
lessc + 空格 + less文件名
最终效果:
@charset "UTF-8";
.themeDark .fade-in-linear-enter-active,
.themeDark .fade-in-linear-leave-active {
-webkit-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
...
3、main.js中引入
echarts
因为项目中使用了大量的echarts,在动态切换肤色时echarts需要重新加载才能改变,因此,需要通过监听全局变量,当改变皮肤时重新渲染echarts。将当前主题存放到vuex中
watch:{
'$store.state.myTheme'() {
this.getAllData();
}
}
map
项目中使用到了腾讯地图,所以也需要更改在不同主题下不同的地图主题。在使用地图时我们知道,在引入地图时需要去引入地图的入口文件,入口文件中包含着需要加载的地图资源,所以我们只需要在腾讯地图官网定义不同的主题颜色,将其style.json保留下来,修改入口文件中的配置。
...
styleSrc: theme == 'themeDark' ? '/static/style.json' : 'https://xxxx/static/cdn/style{id}/style.json',
style3DSrc: theme == 'themeDark' ? '/static/style.json' : 'https://xxxx/static/cdn/style{id}/style.json',
...
js改变主题
做好以上准备工作,在main.js中在改变html的上的属性以及vuex来实现不用刷新更换不同主题。
将需要设置的主题存放到Storage中,以保证刷新后主题颜色不变,为了兼容UI框架(比如dialog会将dom渲染到body外),所以将class置于最顶层html上,改变主题的时候改变html上的class,这样下层所有的less变量将会使用该class下的颜色主题。修改vuex的值,用于触发echarts的刷新。
/**
* 切换肤色
*/
changeColor(type) {
this.themeClass = type;
window.sessionStorage.setItem('themeClass', this.themeClass);
//动态修改html class,为了兼容UI框架,将class置于最顶层
const themeArr = ['themeDark', 'themeLight'];
let tempArr = document.querySelector('html').classList;
tempArr.forEach((item) => {
if (themeArr.includes(item)) {
document.querySelector('html').classList.remove(item);
}
});
document.querySelector('html').classList.add(this.themeClass); //修改echarts的颜色
if (type == 'themeLight') {
Vue.prototype.$themeChartColor = '#333';
} else {
Vue.prototype.$themeChartColor = '#fff';
}
//修改store的值,可用于触发相操作
this.$store.commit('setMyTheme', type);
},
结语
以上便是本次换肤分享,由于该项目刚开发时并没有考虑到后续需要换肤的方案,在本次开发时也遇到很多细节问题,比如之前开发时主题色、各种状态颜色标准使用不一致,改造时我尽量去将一些相近的颜色做到统一,保持系统整体一致性。本次迭代也用了较短的时间实现了这个换肤功能,总体效率上来说这种方案和体验是比较好的。
本文转载于:
https://juejin.cn/post/7282290326068641847
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--前端换肤方案 - element+less无感换肤(无需页面刷新)的更多相关文章
- Android可更换布局的换肤方案
换肤,顾名思义,就是对应用中的视觉元素进行更新,呈现新的显示效果.一般来说,换肤的时候只是更新UI上使用的资源,如颜色,图片,字体等等.本文介绍一种笔者自己使用的基于布局的Android换肤方案,不仅 ...
- .NET Web后台动态加载Css、JS 文件,换肤方案
后台动态加载文件代码: //假设css文件:TestCss.css #region 动态加载css文件 public void AddCss() { HtmlGenericControl _CssFi ...
- Vue.js:轻量高效的前端组件化方案
转发一篇尤老师对vue.js的介绍,了解vue.js的来龙去脉.不过现在已经是2.0了,也有添加一些新的东西,当然有些东西也改了. Vue.js:轻量高效的前端组件化方案 Vue.js 是我在2014 ...
- 前端数据存储方案集合(cookie localStorage等)以及详解 (二)
前端数据存储方案集合(cookie localStorage等)以及详解 (二) 在之前的文章中已经介绍到了 前端存储方案中的 cookie . 但是 cookie 的存储上限是 4KB. 如果超过了 ...
- Modelarts与无感识别技术生态总结(浅出版)
[摘要] Modelarts技术及相关产业已成为未来AI与大数据重点发展行业模式之一,为了促进人工智能领域科学技术快速发展,modelarts现状及生态前景成为研究热点.笔者首先总结modelarts ...
- Spring Cloud实战 | 最八篇:Spring Cloud +Spring Security OAuth2+ Axios前后端分离模式下无感刷新实现JWT续期
一. 前言 记得上一篇Spring Cloud的文章关于如何使JWT失效进行了理论结合代码实践的说明,想当然的以为那篇会是基于Spring Cloud统一认证架构系列的最终篇.但关于JWT另外还有一个 ...
- [后端人员耍前端系列]KnockoutJs篇:使用WebApi+Bootstrap+KnockoutJs打造单页面程序
一.前言 在前一个专题快速介绍了KnockoutJs相关知识点,也写了一些简单例子,希望通过这些例子大家可以快速入门KnockoutJs.为了让大家可以清楚地看到KnockoutJs在实际项目中的应用 ...
- Eclipse 换主题、皮肤、配色,换黑色主题护眼
Eclipse写android代码时,默认的文本和框架都是白色,长时间使用,显得过于刺眼.这里介绍三种方法换黑色护眼配色. 1.系统设置里更改 2.从Eclipse Marketplace里下载主题 ...
- iPhone换电池是原装电池好还是换第三方大容量电池好?
转:https://www.xianjichina.com/news/details_60791.html 最近这段时间苹果降速门事件持续发酵,闹得满城风雨.尽管苹果公司两次致歉,很多果粉都去更换电池 ...
- 无感刷新 Token
什么是JWT JWT是全称是JSON WEB TOKEN,是一个开放标准,用于将各方数据信息作为JSON格式进行对象传递,可以对数据进行可选的数字加密,可使用RSA或ECDSA进行公钥/私钥签名. 使 ...
随机推荐
- NC22604 小A与任务
题目链接 题目 题目描述 小A手头有 n 份任务,他可以以任意顺序完成这些任务,只有完成当前的任务后,他才能做下一个任务 第 i 个任务需要花费 \(x_i\) 的时间,同时完成第 i 个任务的时间不 ...
- Ubuntu22.04 将EFI启动分区迁移到另一块硬盘
机器上有两块硬盘, 一块已经安装了Win10, 另一块新装Ubuntu22.04, 在新硬盘上划分分区的时候, 有分出256M给 BOOT EFI, 但是安装的时候没注意, 启动分区不知道怎的跑到 W ...
- 惠普CP1025后盖传感器松导致不停自检或打印中掉电, 跳闪三角灯
上次修了离合器, 没出两星期又出问题了. CP1025这个型号就是出名的开机特别慢, 正常自检是1分钟, 但是前天我在给机器换完粉盒后, 自检似乎进入了死循环, 一直在自检. 周末才有空看看能不能解决 ...
- Golang微服务框架go-kratos分析:框架架构分析
一.kratos设计理念 这里主要讲解 kratos v2 的设计理念. kratos 框架制定接口规范,然后通过插件来实现具体需求,实现自由定制.可插拔的微服务框架. 我们既可以选择 kratos ...
- kafka学习笔记02-kafka消息存储
kafka消息存储 broker.topic.partition kafka 的数据分布是一个 3 级结构,依次为 broker.topic.partition. 也可以理解为数据库的分库分表,然后还 ...
- 学习go语言编程之标准库
标准库包分类 Golang标准库可以大致按其中库的功能进行以下分类: 分类 对应包 描述 输入输出 bufio,fmt,io,log,flag 这个分类包括二进制以及文本格式在屏幕.键盘.文件以及其他 ...
- 文心一言 VS 讯飞星火 VS chatgpt (201)-- 算法导论15.2 6题
六.用go语言,证明:对 n 个元素的表达式进行完全括号化,恰好需要 n-1 对括号. 文心一言,代码正常运行: 在Go语言中,证明对n个元素的表达式进行完全括号化恰好需要n-1对括号,可以通过数学归 ...
- pycharm中如何改变主题
这边分享一个我自己在用的主题,蛮简约的,关键字高亮显示.再也不用全都是一样的颜色了.网盘地址在最后哈 好了话不多说,教大家如何把主题设置到pycharm中 图1:首先把主题jar包下载下来,然后打开p ...
- React 组件之状态
没有什么是不可能的,只是需要找到正确的方法. 1. 什么是状态? 状态就是组件内部特有数据的载体(组件数据挂载方式),改变数据页面就会刷新,由组件自己设置和更改,也就是说由组件自己产生.维护,使用状态 ...
- 谈一谈如何使用etcd中的事务
本文内容来源于自己学习时所做的记录,主要来源于文章最后的参考链接,如有侵权,请联系删除,谢谢! etcd 是一个 key/value 类型的数据库.既然我们需要存储数据,必然会面临这样一个需求,即希望 ...
