这里实现的国际化使用到了两个包
npm i rgb-hex
npm i css-color-function
css-color-function是用于解析和转换 CSS 颜色函数表达式。
输入示例:"color(#409EFF tint(30%))"
输出示例:"rgb(121, 187, 255)"
这个函数能够处理各种复杂的颜色表达式,比如:
- color(primary shade(10%)) - 将颜色加深 10%
- color(primary tint(30%)) - 将颜色变亮 30%
- color(primary alpha(50%)) - 将颜色透明度设为 50%
rgbHex()是 rgb-hex 库提供的方法,用于将 RGB 颜色值转换为十六进制格式
这两个工具包就实现颜色转换
1.实现动态换肤第-修改element-plus的颜色
实现步骤
1. 根据主色生成色值表
{
"shade-1": "color(primary shade(10%))",
"light-1": "color(primary tint(10%))",
"light-2": "color(primary tint(20%))",
"light-3": "color(primary tint(30%))",
"light-4": "color(primary tint(40%))",
"light-5": "color(primary tint(50%))",
"light-6": "color(primary tint(60%))",
"light-7": "color(primary tint(70%))",
"light-8": "color(primary tint(80%))",
"light-9": "color(primary tint(90%))",
"subMenuHover": "color(primary tint(70%))",
"subMenuBg": "color(primary tint(80%))",
"menuHover": "color(primary tint(90%))",
"menuBg": "color(primary)"
}
//生成色值表
const generateColors = (primary: string) => {
if (!primary) return {};
const colors: Record<string, string> = {
primary
}
Object.keys(formula as FormulaType).forEach(key => {
const value = (formula as FormulaType)[key].replace(/primary/g, primary);
colors[key] = '#' + rgbHex(color.convert(value));
})
return colors;
}
获取当前 element-plus 的默认样式表,并且把需要更改的色值打上标记
import axios from 'axios';
import { version } from 'element-plus/package.json';
//获取原始样式
const getOriginalStyle = async () => {
const url = `https://unpkg.com/element-plus@${version}/dist/index.css`;
const { data } = await axios.get(url);
return getThemeStyle(data);
}
//获取主题样式
const getThemeStyle = (data: string) => {
const colorMap: Record<string, string> = {
'#3a8ee6': 'shade-1',
'#409eff': 'primary',
'#53a8ff': 'light-1',
'#66b1ff': 'light-2',
'#79bbff': 'light-3',
'#8cc5ff': 'light-4',
'#a0cfff': 'light-5',
'#b3d8ff': 'light-6',
'#c6e2ff': 'light-7',
'#d9ecff': 'light-8',
'#ecf5ff': 'light-9'
};
// 添加 RGB 格式颜色映射
const rgbColorMap: Record<string, string> = {
'rgb\\(121\\.3,\\s*187\\.1,\\s*255\\)': 'light-3',
'rgb\\(159\\.5,\\s*206\\.5,\\s*255\\)': 'light-5',
'rgb\\(197\\.7,\\s*225\\.9,\\s*255\\)': 'light-7',
'rgb\\(216\\.8,\\s*235\\.6,\\s*255\\)': 'light-8',
'rgb\\(235\\.9,\\s*245\\.3,\\s*255\\)': 'light-9'
};
// 替换十六进制颜色
Object.keys(colorMap).forEach(key => {
const value = colorMap[key];
data = data.replace(new RegExp(key, 'ig'), value);
});
// 替换 RGB 格式颜色(使用已转义的正则模式)
Object.keys(rgbColorMap).forEach(pattern => {
const value = rgbColorMap[pattern];
data = data.replace(new RegExp(pattern, 'ig'), value);
});
return data;
}
2.找到我们想要替换的样式部分,通过正则完成替换
export const generateNewStyle = async (primaryColor: string) => {
// 1. 根据主色生成色值表
const colors = generateColors(primaryColor);
// 2. 获取当前 element-plus 的默认样式表,并且把需要更改的色值打上标记
let cssText = await getOriginalStyle();
// 3. 遍历生成的色值表,在 默认样式表 进行全局替换
if (colors) {
Object.keys(colors).forEach(key => {
cssText = cssText.replace(new RegExp('(:|\\s+)' + key, 'g'), '$1' + colors[key]);
});
}
return cssText;
};
3.把替换后的样式写入到style标签中,利用样式优先替换固有的样式
export const writeNewStyle = (newStyle: string) => {
const style = document.createElement('style');
style.innerText = newStyle;
document.head.appendChild(style);
};
2.将修改的的颜色应用到自己的样式
这里就不做演示,就是把修改的颜色通过vuex和localstorage存储起来这样就,把它应用到自己的样式,这样就实现了动态换肤