最近在使用vite+react + ant-design 来搭建个人站点,看到网上好多网站都实现了黑白皮肤的切换,并且ant-design帮我们实现了三套主题色,一个默认亮白色暗黑主题紧凑主题。于是我也想来弄一弄。最后还是实现了,打包后也是ok的。

效果

思路

对于网站需要切换主题的话,一般有以下几种办法。

  • 使用css覆盖的方式,由于css基于后面的css覆盖前面的原理,所以这一点也是可以的。但是这一点对于使用less和scss的码友来说,貌似不是一个很好的方法
  • 由于less里面带有一个less.jscdn,可以用来解析是html种使用less文件,但是这个需要注意使用的顺序,需要less的样式文件在前面,less.js的引用在后面,这个对于使用构建工具的同志来说不太友好,打包后less文件都不见了,直接使用路径肯定也是不行。
  • 社区成熟的两个库: antd-theme-webpack-pluginantd-theme-generator,对于我的项目来说貌似都不怎么合适,首先:antd-theme-webpack-plugin这个库是基于webpack来的,我们都知道vite是在开发环境使用esbuild,生产环境使用的是roallup来进行打包。antd-theme-generator这个库的话,把less提升到了运行阶段,我们代码一般会进行打包压缩等,如果使用这个库的话就意味着需要配置less相关的静态资源不能被打包,不然会有问题。

基于上面的思路我做了以下的方法来进行尝试。

我的代码地址是(这个地址不会改动): https://github.com/cll123456/blog

项目做了以下调整:

将ant-design的两个主题,默认主题和暗黑主题引入到我自己的less文件中。然后对此就可以后序实现改动主题色,例如:成功,失败,警告等。如下:

这个引入的顺序需要注意,后引入的变量会覆盖前面的。不会自定义的会不生效

在我点击switch框的时候触发方法。做以下尝试

所有的尝试都是基于下面的第二步,也就是方法,这里面需要做啥事情

尝试一

改变方法的时候直接来动态引入less文件,这样在引入暗黑主题是可以实现的,但是从暗黑主题却切换不过来了。如下:

const handleSkin = (checked: boolean) => {if (checked) {// 明亮主题import('./../assets/style/index.less')} else {// 暗色主题import('./../assets/style/index.dark.less')}}

这个从白的可以切换到黑的原因是,黑色样式覆盖了前面白色的样式,但是如果你再一次覆盖却不行,我估计是选择器权重问题上,ant官方做了改动。如果需要从新切换回来也是有办法的,在明亮主题中直接window.location.reload(),这样是可以切换回来的,如下图:
这样虽然实现了功能,体验肯定是不好的,作为一名前端工程师,肯定是需要非常注重体验的,不然职业生涯的路可能就不会很长。

尝试二

  • 由于尝试一不行,然后我就往import动态引入这边考虑了,我考虑的方向是既然可以动态import引入,那么我可以再一次改变的时候把前一次引入的给remove掉么?
  • 但是我找遍了所有的文件,import导入的是无法remove掉的,import导入是现代浏览器里面的esm的语法。
  • 然后就去网上找各种方法,在ant-design pro中发现实现了这个功能,并且是无刷新的,然后就去gitup上看人家的源码。功夫不负有心人,然后发现人家是动态使用link引入css的方式来实现的,那么我也可以来通过link导入less文件来实现,并且使用less.js的cdn来进行解析。

添加一个addSkin的方法,毕竟需要导入文件,然后来查找原来是否存在,然后进行删除。

// 调用方法
const handleSkin = (checked: boolean) => {if (checked) {// 明亮主题addSkin("./../../src/assets/style/index.less")} else {// 暗色主题addSkin("./../../src/assets/style/index.dark.less")}}
// 添加皮肤的方法
function addSkin(path: string) {let head = document.getElementsByTagName("head")[0];const getLink = head.getElementsByTagName('link');// 查找link是否存在,存在的话需要删除domif (getLink.length > 0) {for (let i = 0, l = getLink.length; i < l; i++) {if (getLink[i].getAttribute('data-type') === 'theme') {getLink[i].remove();}}}// 查找script是否存在const getScript = head.getElementsByTagName('script');if (getScript.length > 0) {for (let i = 0, l = getScript.length; i < l; i++) {if (getScript[i].getAttribute('data-type') === 'theme') {getScript[i].remove();}}}// 最后加入对应的主题和加载less的js文件let link = document.createElement("link");link.dataset.type = "theme";link.href = path;link.rel = "stylesheet";link.type = "text/css";head.appendChild(link);// 这个less.js一定要放到后面才行let script = document.createElement('script');script.type = 'text/javascript';script.dataset.type = 'theme';script.src = 'https://cdn.bootcdn.net/ajax/libs/less.js/4.1.1/less.js'head.appendChild(script)
}

这种方法是动态改变link标签的样式来实现的,在生产环境是没有任何问题,但是在开发环境就不行了,打包后路径不存在。肯定是不行的,接下来我就去找vite如何静态资源复制到打包的文件,方法找到了。但是我的less里面引用了antd里面的less,里面的也不用打包? 我觉得不太好,因此再一次放弃。

尝试三

既然直接使用less文件不行,那我可以使用css不,和ant-design pro里面一样的,我也来引用css文件,接下来就往这个方向。
我直接打印了,import dark from './xxxx'.less 发现既然是一个字符串。

是编译好的字符串,那我直接使用style标签就好了。说干就往下干。

import dark from './../assets/style/index.dark.less'
import lighter from './../assets/style/index.less'// 调用方法
const handleSkin = (checked: boolean) => {if (checked) {// 明亮主题addSkin(lighter)} else {// 暗色主题addSkin(dark)}}
// 添加皮肤的方法
function addSkin(content: string) {let head = document.getElementsByTagName("head")[0];const getStyle = head.getElementsByTagName('style');// 查找style是否存在,存在的话需要删除domif (getStyle.length > 0) {for (let i = 0, l = getStyle.length; i < l; i++) {if (getStyle[i].getAttribute('data-type') === 'theme') {getStyle[i].remove();}}}// 最后加入对应的主题和加载less的js文件let styleDom = document.createElement("style");styleDom.dataset.type = "theme";styleDom.innerHTML = content;head.appendChild(styleDom);
}
  • 这里有一个细节就是,样式导入必须在顶部导入,不然vite会检测不到,不能使用动态导入,打包会经过treeshake去掉.
  • 其实这里还有一个问题,那就是css打包后会比较大,毕竟引入了两份,这个问题就留给码友了,自己去vite获取其他的构建工具(webpack, gulp等)上找静态资源太大怎么处理。

总结

在真实的调试中肯定是不止这三遍尝试的,这里只记录走向成功的关键三步。More interest, less interests (多一些兴趣爱好的向往,少一些功名利禄的追求)

ant-design实现主题暗黑主题 和 亮色主题的 切换(实现网站黑白皮肤)相关推荐

  1. Ant Design Pro 企业级后台实战(73 个视频)

    Ant Design Pro 企业级后台实战(73 个视频) Ant Design Pro 企业级后台实战 #1 介绍(声音已调到毫无杂音_) Ant Design Pro 企业级后台实战 #2 学习 ...

  2. ant design的自定义主题 modifyVars无效的原因

    ant design的自定义主题 config-overrides.js文件 const {override,fixBabelImports,addLessLoader} = require('cus ...

  3. Ant design vue动态主题切换的坑与一般性方法

    本文原创,并且以吐槽为主,下面开始: Ant design vue是很优秀的框架,不过对于一般小白用户(比如我),文档方面不够友好.官方给出了主题自定义色彩的方案,但是太过于简陋,网上很多技术解决方案 ...

  4. WordPress Qui-Pure V2.22发布纯文本主题-暗黑模式

    主题介绍: Qui-Pure是我开发的第一款主题,纯文本展示博客类型,后台控制是否加载图片/轮播图,页面布局改成图文排版!兼容erphpdown,加入个人中心,由于技术学习来源互联网,WordPres ...

  5. 前端技术学习记录:react+dvajs+ant design实现暴走计算器的页面重构(二)

    前端技术学习记录:react+dvajs+ant design实现暴走计算器的页面重构(二) 前言 定义 Model connect 起来 更新state 拥抱变化 主题切换 更换页面 获取当前设备类 ...

  6. ant design后台模板-1.前端环境搭建

    学习了一段时间的React,试着搭建一个后台管理的模板,算是这一段时间的学习总结,前端将采用create-react-app作为脚手架,引用react-router进行路由处理,后台将采用spring ...

  7. Ant Design 3.16.2 发布,企业级 UI 设计语言

    百度智能云 云生态狂欢季 热门云产品1折起>>>   Ant Design 3.16.2 发布了.Ant Design 是阿里开源的一套企业级的 UI 设计语言和 React 实现, ...

  8. ant design pro(一)安装、目录结构、项目加载启动【原始、以及idea开发】

    一.概述 1.1.脚手架概念 编程领域中的"脚手架(Scaffolding)"指的是能够快速搭建项目"骨架"的一类工具.例如大多数的React项目都有src,p ...

  9. Ant Design离线使用Icon图标资源

    使用环境:开发环境内网 node + React + antd    第一种方法:[推荐] 第一种方法[原创]: 想在网上找到的第二种方法,试验一下可以.但是我不想 失去按需加在css的功能,所以自己 ...

最新文章

  1. Python ATM
  2. java使用Redis4--主从复制
  3. 公告牌为什么有些是纸质,有些是电子的
  4. ubuntu18.10终端的方块改成竖线
  5. mysql怎么改字体编码_mysql怎么改字符编码?
  6. SQL Server CLR全功略之一---CLR介绍和配置
  7. php首页遍历出商品详情页,ECSHOP首页/分类页/详情页各页面调用显示销量
  8. android 动画 图片 内存溢出,Android有效解决加载大图片时内存溢出的问题
  9. web 网页设计规范介绍
  10. 再见python你好julia_再见,Python2。你好,Python3
  11. Cobbler自动部署CentOS系统
  12. Windows平台精选软件工具列表-Windows绝赞应用
  13. 家装市场分析:2022年家装企业比例稳步上升
  14. R语言-回归系数的极大似然估计
  15. 解密!看蚂蚁金服智能调度技术如何优化客服中心资源调配
  16. mysql mycat水平分库_MyCat水平分库
  17. 梦想汽车 NFT 系列
  18. 【秒懂音视频开发】15_AAC编码实战
  19. 翻译:(MPN-Cov)Is Second-order Information Helpful for Large-scale Visual Recognition?
  20. Google、迅雷与李开复、周鸿祎的那点破事

热门文章

  1. Mathtype中使用inline导致word行间距不一致的问题解决方案
  2. 3M年度调查显示,疫情挑战下中国受访者对科学的信任度居全球首位
  3. 关于我们-找学术会议,上MeetConf!科研人都在看的学术会议网站
  4. 一文读懂「用户行为数据」的采集、分析和应用
  5. Excel基础学习(2013及以上版本)
  6. 苹果切换输入法_使用苹果手机的注意啦!iphone输入法不好用?这些使用技巧教给你...
  7. IE浏览器里面链接点击在Chrome浏览器打开
  8. 树--先序遍历构建二叉树
  9. 使用 HTML5 和 CSS3 创建现代 Web 站点
  10. 360更新补丁之后把Outlook弄坏了