什么是换肤?
更换页面的主题或配色,简单来讲就是更换css。
项目实现的换肤效果是怎样的?
- 支持两种主题配色切换:深色和蓝绿色
- 使用webpack生成主题
- 切换主题时页面不会刷新
- 支持多种格式,如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);
}
};
}