1. 程式人生 > >antd在線換膚定制功能

antd在線換膚定制功能

希望 css樣式 mas tdi success 作用 them sign product

最近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

antd在線換膚定制功能