换肤

使用前的准备

  • 安装 antd-theme-generator (color.js脚本中使用该库进行打包)

  • 安装 postcss-css-variables (考虑var()兼容性)

  • html模板中引入less.js库,并设置less配置项,引入新增的less文件

1
2
3
4
5
6
7
8
9
10
<!--在线编译的less文件 -->
<link rel="stylesheet/less" type="text/css" href="/assets/color.less" />
<script>
<!--less配置项-->
window.less = {
async: false, // 同步加载的方式引入
env: 'production' // 生产环境不打log 不报错,数据存入localstorage中
};
</script>
<script src="https://cdn.bootcss.com/less.js/2.7.2/less.min.js"></script>

使用中的步骤

  • 项目目录下新建color.js文件,修改package.json中脚本命令,在执行前先node color && yarn start
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const path = require('path');
const {generateTheme} = require('antd-theme-generator');

const options = {
stylesDir: path.join(__dirname, './src/assets/less'),
antDir: path.join(__dirname, './node_modules/antd'),
varFile: path.join(__dirname, './src/assets/less/vars.less'),
mainLessFile: path.join(__dirname, './src/assets/less/main.less'),
themeVariables: [
'@primary-color',
'@btnActiveColor'
],
outputFilePath: path.join(__dirname, './public/assets/color.less'),
customColorRegexArray: [/^darken\(.*\)$/]
};

generateTheme(options)
.then(less => {
console.log('Theme generated successfully');
})
.catch(error => {
console.log('Error', error);
});
  • 新增一个css变量需要以下四步(如果不需要考虑兼容性,步骤2和3可以省略)
  1. 在color.js的themeVariables数组中添加less变量名@btnColor(未在此处申明的变量后面是无法通过modifyVars修改变量值的)

  2. 在vars.less中添加less变量的初始值@btnColor:#fffffe后,在:root{}中设置同名css变量并赋值--btnColor: @btnColor

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 引入antd主题文件
    @import '~antd/lib/style/themes/default.less';

    // 改写antd默认变量值
    @primary-color: #ffc847;
    // 添加自定义变量
    @btnActiveColor: #fffffe;

    // 搭配css变量,控制非antd组件的样式
    :root {
    --primary: @primary-color;
    --btnActiveColor: @btnActiveColor;
    }
  3. cssVariabelConfig.js文件中,配置css变量的默认值(用于webpack打包时,生成兼容不支持css变量的环境)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    // cssVariabelConfig.js
    module.exports = {
    '--primary-color': "#ffc847",
    '--btnActiveColor': '#fffffe',
    }

    // webpack
    const cssvariables = require('postcss-css-variables');
    const cssVariablesConfig = require('./theme/cssVariabelConfig')

    {
    test: /\.less$/,
    use: [
    require.resolve('style-loader'),
    require.resolve('css-loader'), {
    loader: require.resolve('postcss-loader'),
    options: {
    ident: 'postcss',
    plugins: () => [
    require('postcss-flexbugs-fixes'),
    autoprefixer({
    browsers: [
    'last 2 versions',
    ]
    }),
    cssvariables({
    preserve: true,
    preserveInjectedVariables: false,
    variables:cssVariablesConfig
    })
    ],
    },
    }, {
    loader: require.resolve('less-loader'),
    options: {
    // modifyVars: antdTheme, // 如果配了这属性 要去掉
    },
    },
    ],
    }
  4. theme.js中,配置各个主题下变量@btnColor的实际值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    default: {
    '@primary-color': '#ffc847',
    '@text-color': '#ffffff'
    },
    blue: {
    '@primary-color': '#4560e6',
    '@text-color': '#333'
    },
    yellow: {
    '@primary-color': '#ff6600',
    '@text-color': '#333'
    }
    }
  • 调用less.js的modifyVars(option)方法修改主题option:{‘@primary-color’: ‘#fff’}
    1
    2
    3
    4
    5
    6
    7
    8
    window.less
    .modifyVars(option)
    .then(()=>{
    <!--成功-->
    })
    .catch(e=>{
    <!--失败-->
    })

使用后的问题

  • 只适用于less文件

  • color.js生成的文件内容会存到localstorage中(内容较多)

  • 内联和行内样式,涉及到主题的(color, background-color, border-color等色值属性)应全部改写到less文件中

  • antd的主题样式在打包时就已经全部引入,但不会影响antd已有的按需加载

  • antd变量与css变量在命名时需要区分(驼峰和横线)避免在自定义的样式中修改了antd的变量

  • 针对一些其他库(类似echarts)的色值匹配,抽出了公共方法,可根据当前主题类型,使用该类型中的配置属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 获取当前账户主题
    export const getActiveUserTheme = () => {
    let userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}');
    let themeCustom = JSON.parse(localStorage.getItem('themeCustom') || '{}');
    let type = themeCustom[userInfo.id] || 'default';
    let activeTheme = themeConfig[type];
    return {
    type, // 主题类型
    activeTheme // 该主题类型下的配置对象
    };
    };
觉得不错的话可以打赏哦