antd在线换肤定制功能

简介: 最近react项目,用的antd框架,然后看见他的antdPro例子里面有个定制功能很帅,老大说做,那就做吧,鼓捣了一晚终于实现了。先看预览效果吧css换肤入行前端的时候经常看鱼哥(张鑫旭)的博客,记得看过 这篇 ,当时很惊叹,原理其实很简单,就是我们最能想到的方式,多个css,然后用JS替换从而达到换肤效果。

最近react项目,用的antd框架,然后看见他的antdPro例子里面有个定制功能很帅,老大说做,那就做吧,鼓捣了一晚终于实现了。

先看预览效果吧

css换肤

入行前端的时候经常看鱼哥(张鑫旭)的博客,记得看过 这篇 ,当时很惊叹,原理其实很简单,就是我们最能想到的方式,多个css,然后用JS替换从而达到换肤效果。但是这个有局限性,比如我们用的是antdUI库,我们不可能每个颜色都去搞个css吧。当时现在我们有less,sass,而且原生的css也有变量var了,所以新时代我们有新技术达到这个效果。

less换肤

其实antd官网是有 定制主题 的,但是是静态的,通过打包之前去设置一些config,less变量从而达到定制效果,但是这显然不是我们想要的==线上实时==换肤效果。

最初我的思路是用node去实时生成一个webpack.config.base的配置文件,但是这样只能在开发环境实现换肤,生成环境是没办法的。然后网上有人说,用less去生成多个css文件,这不又走了以前的老路吗。最后没办法我把antdPro的源码拿来看了下,终于找到了解决办法,antd-theme-generator

步骤

  • 这里我的项目是在自己写的 webpack4-react脚手架 的基础上做修改的,如果你用的create-react-app或者其他的脚手架可能会有相应修改。
  • 安装cnpm i antd-theme-generator --save
  • index.html
<body>
    <link rel="stylesheet/less" type="text/css" href="static/color.less" /> //主要是这个起作用
    <script>
        window.less = {
            async: false,
            env: 'production'
        };
    </script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js"></script>
    <noscript>
        You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
</body>
  • 根目录添加color.js
const path = require('path');
const { generateTheme, getLessVars } = require('antd-theme-generator');

const options = {
  stylesDir: path.join(__dirname, './src/styles'),    //对应具体位置
  antDir: path.join(__dirname, './node_modules/antd'), //对应具体位置
  varFile: path.join(__dirname, './src/styles/vars.less'), //对应具体位置
  mainLessFile: path.join(__dirname, './src/styles/main.less'), //对应具体位置
  themeVariables: [
    '@primary-color',
    '@secondary-color',
    '@text-color',
    '@text-color-secondary',
    '@heading-color',
    '@layout-body-background',
    '@btn-primary-bg',
    '@layout-header-background'
  ],
  indexFileName: 'index.html',
  outputFilePath: path.join(__dirname, './src/static/color.less'),
}

generateTheme(options).then(less => {
  console.log('Theme generated successfully');
})
  .catch(error => {
    console.log('Error', error);
  });
  • src添加styles文件夹,里面有vars.less和main.less
//vars.less
@import "~antd/lib/style/themes/default.less";
@link-color: #00375B;
@primary-color: #00375B;
:root { 
    --PC: @primary-color;   //color.less中加入css原生变量:--PC
 }

//main.less
//可为空,只是为了不报错才引入
  • package.json
//为了每次自动node color.js,所以scripts里面修改下
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "node color &&  webpack-dev-server --config webpack.config.dev.js", 
    "start": "npm run dev",
    "build": "node color && webpack --config webpack.config.prod.js"
  },
  • 使用,启动后直接window.less.modifyVars就可以了
window.less
    .modifyVars(
        {
            '@primary-color': '#ee5e7b',
            '@link-color': '#ee5e7b',
            '@btn-primary-bg': 'ee5e7b',
        }
    )
    .then(() => { })
    .catch(error => {
        message.error(`Failed to update theme`);
    });
  • 最后,打包后注意放入环境后打开,否则会报错。

原理

我们发现其实他生效主要就是靠color生成一个color.less文件,然后我打开color.less文件看了下,发现原来是利用的less可以写逻辑这个特性实现的,从而通过window.less.modifyVars去动态的改变less变量。

其他

现在antd的换肤问题解决了,但是我们自己的css样式怎么办呢,比如我有个标题想用主题色,我怎么去拿到这个颜色呢。

  • 起初我是这样实现的vars.less增加
//vars.less
 .primary-color{
     color:@primary-color
 }

这样.primary-color就会打入生成的color.less里面,然后我们就可以用了,当时这样有些地方就不方便,比如box-shadow: 1px 1px 1px 1px #d23333;,我们怎么办,难道每次都要写在vars.less里面吗

  • 所以这里我用了css的原生变量var
//vars.less
:root { 
    --PC: @primary-color;
 }

然后就可以使用box-shadow: 1px 1px 1px 1px var(--PC);

本地保存

用户设置颜色后,可以用缓存或者localStorage保存,这就不多说了

预览效果

源码

最后

大家好,这里是「 TaoLand 」,这个博客主要用于记录一个菜鸟程序猿的Growth之路。这也是自己第一次做博客,希望和大家多多交流,一起成长!文章将会在下列地址同步更新……
个人博客:www.yangyuetao.cn
小程序:TaoLand

目录
相关文章
|
小程序
【微信小程序开发】自定义组件以及页面布局设计 )
【微信小程序开发】自定义组件以及页面布局设计 )
79 0
|
缓存 小程序
微信小程序使用vant组件样式不生效的问题
微信小程序使用vant组件样式不生效的问题
1022 0
vue2实现markdown编辑器,实现同步滚动,实时预览等功能
vue2实现markdown编辑器,实现同步滚动,实时预览等功能
|
2月前
|
缓存 资源调度 JavaScript
Vue集成Excalidraw实现在线画板功能
Excalidraw是一款开源在线绘图工具,适用于白板、思维导图、原型设计等场景。支持手绘风格、多种图形元素、导出功能及多人协作,深受开发者喜爱。本文档介绍了如何在Vue项目中集成Excalidraw,包括安装依赖、配置文件修改、页面添加等步骤,帮助开发者快速上手。
223 0
Vue集成Excalidraw实现在线画板功能
|
6月前
|
小程序 前端开发
【微信小程序-原生开发】TDesign 实战模板——聊天气泡
【微信小程序-原生开发】TDesign 实战模板——聊天气泡
135 0
|
JSON 小程序 前端开发
五分钟上手Vant,快速搭建小程序界面样式
五分钟上手Vant,快速搭建小程序界面样式
173 0
|
8月前
|
开发框架 小程序 JavaScript
高颜值微信小程序 UI 组件库!
高颜值微信小程序 UI 组件库!
364 1
|
API 开发者 索引
Flutter笔记:发布一个多功能轮播组件 awesome_carousel
awesome_carousel 模块是一个Flutter轮播图模块。可以实现包括自定义指示器、动画、滚动等等众多功能。能够指定相当多地细节(可以参考 API 部分了解)本文给出 awesome_carousel 模块的两个简单的用法示例。
340 0
|
资源调度 前端开发 JavaScript
Vue3.0入门 + Vant3.0移动端实践(一)环境搭建及首页底部导航栏设计
Vue3.0入门 + Vant3.0移动端实践(一)环境搭建及首页底部导航栏设计
|
JavaScript 前端开发 API
Vue3.0入门 + Vant3.0移动端实践(二)轮播图模块封装及首页完善
Vue3.0入门 + Vant3.0移动端实践(二)轮播图模块封装及首页完善