前端换肤方案 - 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);
},

结语

以上便是本次换肤分享,由于该项目刚开发时并没有考虑到后续需要换肤的方案,在本次开发时也遇到很多细节问题,比如之前开发时主题色、各种状态颜色标准使用不一致,改造时我尽量去将一些相近的颜色做到统一,保持系统整体一致性。本次迭代也用了较短的时间实现了这个换肤功能,总体效率上来说这种方案和体验是比较好的。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

odoo16 取消“系统各功能状态日报”的邮件

odoo16默认情况下每周都会发送一个“系统各功能状态日报”的邮件&#xff0c;而且是所有人都发&#xff0c; 这个功能在哪配置呢&#xff1f; 今天研究了一下&#xff0c; 线索是“系统各功能状态日报”&#xff0c;先全文检索吧 #. module: digest #: model:digest.digest,na…

视频如何压缩?视频压缩到100M以内这样做

在日常生活中&#xff0c;我们常常需要处理各种各样的视频文件&#xff0c;但往往视频的大小会给我们的存储和传输带来困扰。那么&#xff0c;如何有效地压缩视频呢&#xff1f;下面就给大家分享三种解决方法&#xff0c;一起来看看吧。 方法一&#xff1a;嗨格式压缩大师 这是…

【flutter】架构之商城main入口

架构之商城main入口 前言一、项目模块的划分二、入口main的配置三、配置文件怎么做总结 前言 本栏目我们将完成一个商城项目的架构搭建&#xff0c;并完善中间的所有功能&#xff0c;总页面大概200个&#xff0c;如果你能看完整个栏目&#xff0c;你肯定能独立完成flutter 项目…

全流程ARCGIS Pro技术应用教程

详情点击公众号链接&#xff1a;全流程ARCGIS Pro技术应用教程 前沿 GIS是利用电子计算机及其外部设备&#xff0c;采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲&#xff0c;它是在一定的地域内&#xff0c;将地理空间信息和 一些与该地域地理信息相关…

基于springboot+vue的大学生竞赛交流系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

【内网穿透】在Ubuntu搭建Web小游戏网站,并将其发布到公网访问

目录 前言 1. 本地环境服务搭建 2. 局域网测试访问 3. 内网穿透 3.1 ubuntu本地安装cpolar 3.2 创建隧道 3.3 测试公网访问 4. 配置固定二级子域名 4.1 保留一个二级子域名 4.2 配置二级子域名 4.3 测试访问公网固定二级子域名 前言 网&#xff1a;我们通常说的是互…

从技术创新到应用实践,百度智能云发起大模型平台应用开发挑战赛!

大模型已经成为未来技术发展方向的重大变革&#xff0c;热度之下更需去虚向实&#xff0c;让技术走进产业场景。在这样的背景下&#xff0c;百度智能云于近期发起了“百度智能云千帆大模型平台应用开发挑战赛”。 挖掘大模型落地应用 千帆大模型平台应用开发挑战赛启动 在不久…

适合新手自学的网络安全基础技能“蓝宝书”:《CTF那些事儿》

CTF比赛是快速提升网络安全实战技能的重要途径&#xff0c;已成为各个行业选拔网络安全人才的通用方法。但是&#xff0c;本书作者在从事CTF培训的过程中&#xff0c;发现存在几个突出的问题&#xff1a; 1&#xff09;线下CTF比赛培训中存在严重的“最后一公里”问题&#xf…

Unity中关于多线程的一些事

一.线程中不允许调用unity组件api 解决方法&#xff1a;可以使用bool值变化并且在update中监测bool值变化来调用关于unity组件的API. 二.打印并且将信息输出到list列表中 多线程可能同时输出多条信息。输出字符串可以放入Queue队列中。队列可以被多线程插入。 三.启用socke…

用flex实现grid布局

1. css代码 .flexColumn(columns, gutterSize) {display: flex;flex-flow: row wrap;margin: calc(gutterSize / -2);> div {flex: 0 0 calc(100% / columns);padding: calc(gutterSize / 2);box-sizing: border-box;} }2.用法 .grid-show-item3 {width: 100%;display: fl…

Linux环境下使用SVN快速访问资料库?试试使用cpolar端口映射

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

电脑C盘爆红怎么办?(小白篇)

文章目录 前言&#xff1a;1、清理临时和系统文件2、更改电脑默认软件安装位置3、微信、QQ文件存储路径放在其它盘4、卸载一些不常用的软件彩蛋 前言&#xff1a; C盘作为电脑的系统盘&#xff0c;如果出现爆满或者剩余空间很小整个C盘变红&#xff0c;这样会导致电脑系统运行…

ScrollView如何裁剪粒子特效

1&#xff09;ScrollView如何裁剪粒子特效 2&#xff09;Unreal在移动设备中无法使用Stat命令获取到GPU Thread的耗时 3&#xff09;Unity中如何看到相机视野范围内的剔除结果 这是第354篇UWA技术知识分享的推送&#xff0c;精选了UWA社区的热门话题&#xff0c;涵盖了UWA问答、…

CSS 中的曲线时间轴

在本文中,我们将为您的网站构建一个弯曲的时间线,您稍后可以在您的作品集中使用它来显示您的工作历史或您想要的其他内容。让我们首先看看我们正在构什么 现在您已经看到了我们要做的事情,所以让我们开始编写代码 <!DOCTYPE html> <html lang="en">…

机器学习总结

对以下文章机器学习总结 什么是深度学习?最易懂的机器学习入门文章-CSDN博客 人工智能和机器学习之间的关系 人工智能是一个最宽泛的概念&#xff0c;是一个研究领域&#xff0c;同时也是一个实现目标&#xff0c;而机器学习则是实现这一目标的一类方法。深度学习只是机器学…

视频号如何下载到相册,无水印高清下载保存到手机相册

微信视频号是一个全新的内容记录与创作平台&#xff0c;他不同于订阅号与服务号&#xff0c;很多人都有这么一个需求视频号视频怎么下载保存到手机相册&#xff0c;不同的人思路要有所不同&#xff0c;今天这篇内容就和大家聊聊如何下载并保存到手机相册。 视频号如何下载到相…

微调大模型工具-LoRA

介绍 微调 在机器学习领域&#xff0c;大型模型已成为解决各种问题的首选解决方案。从自然语言处理到计算机视觉&#xff0c;这些计算能力的庞然大物都表现出了无与伦比的性能。然而&#xff0c;这种性能实际上是有代价的。微调这些大型模型以适应特定任务或领域是一个资源密…

Spring MVC常见面试题

Spring MVC简介 Spring MVC框架是以请求为驱动&#xff0c;围绕Servlet设计&#xff0c;将请求发给控制器&#xff0c;然后通过模型对象&#xff0c;分派器来展示请求结果视图。简单来说&#xff0c;Spring MVC整合了前端请求的处理及响应。 Servlet 是运行在 Web 服务器或应用…

汽车电子相关术语

SOA SOA&#xff08;Service-Oriented Architecture&#xff0c;面向服务的架构&#xff09;是一种在计算机环境中设计、开发、部署和管理离散模型的方法。是由Garnter1996年提出的概念&#xff0c;将应用程序的不同功能单元&#xff08;称为服务&#xff09;进行拆分&#xf…

HDMI之HDCP 2.3

Authentication and Key Exchange Without Stored Km With Stored Km HDCP2Version DDC时序 协议截图 Bit2为1,可知DUT设备支持HDCP 2.2及以上版本 RxStatus DDC时序 协议截图 <