项目换肤方案

1,121 阅读2分钟

什么是换肤?

更换页面的主题或配色,简单来讲就是更换css。

项目实现的换肤效果是怎样的?

  1. 支持两种主题配色切换:深色和蓝绿色
  2. 使用webpack生成主题
  3. 切换主题时页面不会刷新
  4. 支持多种格式,如css, less,sass(项目使用less)

实现步骤

1、创建主题文件夹

themes文件夹下并列三个主题文件,将默认主题写入default.less。

//default.js
@import './dark.less'; //深色主题作为默认色

2、抽取变量(dark.less和green.less中的写法)

抽取主题颜色设为'颜色变量',并赋值给'样式变量'。
颜色变量 样式变量 注:这里要提及为什么项目要用less, 主要原因是:我们运用了大量的dpl中的组件,dpl是基于antd的,要覆盖dpl中的颜色,那么只需要知道到对应的antd中的变量,修改这个变量即可。

// antd中的menu backgroud
//dafault.less
@component-background: #fff;
@menu-bg: @component-background;

真正使用样式变量:

// portalMenu.less
@import '/xx/xx/default.less';
.menu-copy-right {
	background: @menu-bg;	
 }

3、安装和配置themes-switch

安装:

npm install themes-switch --save

webpack.config.js 中的配置:

const ThemesGeneratorPlugin = require('themes-switch/ThemesGeneratorPlugin');

module.exports = {
 
  plugins: [
    new ThemesGeneratorPlugin({
      srcDir: 'src',  //代码目录
      themesDir: 'src/assets/themes', //主题目录
      outputDir: 'static/css', //生成的文件目录
      defaultStyleName: 'default.less' //默认主题文件
    })
  ]
};

ThemesGeneratorPlugin 会去扫描指定的主题目录,然后为所有主题自动生成独立的文件。下图为build/static/css中的主题文件。

4、使用changeTheme切换主题

import { changeTheme } from 'themes-switch';

changeTheme(name, url);
changeTheme('themes-dark', 'css/themes-dark.css');

// 项目中的实现
const THEMES = process.themes; //用来获取主题信息
this.themeChanger = autorun(() => {
    const {theme} = sessionStore; // 每次切换主题都会更改sessionStore中的theme
    cosnt themeKey = THEME_KEYS[theme]; //constants
    if (typeof THEMES === 'object') {
      changeTheme(themeKey, THEMES[themeKey]);
    }
  });

changeTheme做了什么?一起来看源码

var THEME_KEY = 'theme';
var PLUGIN_KEY = 'pkey';
var PLUGIN_VALUE = 'themes-switch';

function changeTheme(theme, themeUrl, onLoad) {
  var head = document.head || document.getElementsByTagName('head')[0];
  var links = head.getElementsByTagName('link');
  var oldTheme;

  if (links && links.length > 0) {
    for (var i = 0; i < links.length; i++) {
      if (getAttribute(links[i], PLUGIN_KEY) === PLUGIN_VALUE) {
        oldTheme = links[i];
        break;
      }
    }
  }

  var link = document.createElement('link');
  link.rel = 'stylesheet';
  link.href = themeUrl;
  setAttribute(link, THEME_KEY, theme);
  setAttribute(link, PLUGIN_KEY, PLUGIN_VALUE);
  head.appendChild(link);

  link.onload = function () {
    removeNode(oldTheme);

    if (onLoad) {
      onLoad(link);
    }
  };
}

参考链接: www.npmjs.com/package/the…