调色板自定义主题颜色
关键方案
element-plus
的cssjson$--colors: (
"primary": (
"base": #11C974,
),
"success": (
"base": #11C974,
),
"warning": (
"base": #EBA826,
),
"danger": (
"base": #F77062,
),
"error": (
"base": #f5222d,
),
);
@forward "element-plus/theme-chalk/src/common/var.scss" with (
$colors: $--colors !default,
);
vite.config.js
json css: {
preprocessorOptions: {
scss: {
additionalData: `@use "src/assets/styles/element/index.scss";
@use "src/assets/styles/element/dark.index.scss";
`,
},
},
},
JavaScript/** 变量前缀 */
const PRE = '--el-color-primary';
/** 浅色变量前缀 */
const PRE_LIGHT = `${PRE}-light`;
/** 深色变量前缀 */
const PRE_DARK = `${PRE}-dark`;
/** 色阶 */
const Levels = [3, 5, 7, 8, 9];
/** 白色 */
const WHITE = '#FFFFFF';
/** 黑色 */
const BLACK = '#000000';
export {
PRE, PRE_LIGHT, PRE_DARK, Levels, WHITE, BLACK,
};
JavaScriptimport { onBeforeMount } from 'vue';
import {
PRE, PRE_DARK, PRE_LIGHT, Levels, WHITE, BLACK,
} from './element';
const html = document.documentElement;
/**
* 混合颜色
*/
const mix = (color1, color2, weight) => {
// eslint-disable-next-line no-param-reassign
weight = Math.max(Math.min(Number(weight), 1), 0);
const r1 = parseInt(color1.substring(1, 3), 16);
const g1 = parseInt(color1.substring(3, 5), 16);
const b1 = parseInt(color1.substring(5, 7), 16);
const r2 = parseInt(color2.substring(1, 3), 16);
const g2 = parseInt(color2.substring(3, 5), 16);
const b2 = parseInt(color2.substring(5, 7), 16);
const r = Math.round(r1 * (1 - weight) + r2 * weight);
const g = Math.round(g1 * (1 - weight) + g2 * weight);
const b = Math.round(b1 * (1 - weight) + b2 * weight);
// eslint-disable-next-line no-underscore-dangle
const _r = (`0${(r || 0).toString(16)}`).slice(-2);
// eslint-disable-next-line no-underscore-dangle
const _g = (`0${(g || 0).toString(16)}`).slice(-2);
// eslint-disable-next-line no-underscore-dangle
const _b = (`0${(b || 0).toString(16)}`).slice(-2);
return `#${_r}${_g}${_b}`;
};
/**
* 更换颜色的方法
* @param color 颜色
*/
const changeTheme = (color) => {
if (!color) {
console.warn('未获取到颜色的值');
return;
}
// 设置主要颜色变量 --el-color-primary
html.style.setProperty(PRE, color);
// 循环设置色阶颜色
// --el-color-primary-light-${level}
Levels.forEach((level) => {
html.style.setProperty(`${PRE_LIGHT}-${level}`, mix(color, BLACK, 1 * 0.1));
});
// 设置主要暗色
// --el-color-primary-dark-2
const dark = mix(color, BLACK, 0.2);
html.style.setProperty(`${PRE_DARK}-2`, dark);
localStorage.setItem('theme-color', color);
};
// eslint-disable-next-line import/prefer-default-export
export function useElementPlusTheme(color) {
onBeforeMount(() => {
changeTheme(color);
});
return {
changeTheme,
};
}
在使用Element Plus开发Vue项目时,我们经常需要自定义主题色以满足项目的设计需求。本文将介绍如何通过JavaScript动态修改Element Plus的主题色,实现灵活的主题定制功能。
Element Plus的主题系统是基于CSS变量实现的。通过修改这些CSS变量,我们可以动态更改组件的主题色。主要的变量包括:
--el-color-primary
: 主题色--el-color-primary-light-{n}
: 主题色的亮色变体(n可为3,5,7,8,9)--el-color-primary-dark-2
: 主题色的暗色变体首先,我们定义必要的常量:
javascriptconst PRE = '--el-color-primary';
const PRE_LIGHT = `${PRE}-light`;
const PRE_DARK = `${PRE}-dark`;
const Levels = [3, 5, 7, 8, 9];
const WHITE = '#FFFFFF';
const BLACK = '#000000';
实现一个颜色混合函数,用于生成不同明度的颜色:
javascriptconst mix = (color1, color2, weight) => {
weight = Math.max(Math.min(Number(weight), 1), 0);
// 将16进制颜色转换为RGB
const r1 = parseInt(color1.substring(1, 3), 16);
const g1 = parseInt(color1.substring(3, 5), 16);
const b1 = parseInt(color1.substring(5, 7), 16);
const r2 = parseInt(color2.substring(1, 3), 16);
const g2 = parseInt(color2.substring(3, 5), 16);
const b2 = parseInt(color2.substring(5, 7), 16);
// 计算混合后的RGB值
const r = Math.round(r1 * (1 - weight) + r2 * weight);
const g = Math.round(g1 * (1 - weight) + g2 * weight);
const b = Math.round(b1 * (1 - weight) + b2 * weight);
// 转换回16进制
const _r = (`0${(r || 0).toString(16)}`).slice(-2);
const _g = (`0${(g || 0).toString(16)}`).slice(-2);
const _b = (`0${(b || 0).toString(16)}`).slice(-2);
return `#${_r}${_g}${_b}`;
};
实现主题切换的核心函数:
javascriptconst changeTheme = (color) => {
if (!color) {
console.warn('未获取到颜色的值');
return;
}
// 设置主题色
document.documentElement.style.setProperty(PRE, color);
// 设置不同亮度的主题色
Levels.forEach((level) => {
document.documentElement.style.setProperty(
`${PRE_LIGHT}-${level}`,
mix(color, BLACK, 1 * 0.1)
);
});
// 设置暗色主题色
const dark = mix(color, BLACK, 0.2);
document.documentElement.style.setProperty(`${PRE_DARK}-2`, dark);
// 保存主题色到本地存储
localStorage.setItem('theme-color', color);
};
将功能封装为Vue组合式API:
javascriptexport function useElementPlusTheme(color) {
onBeforeMount(() => {
changeTheme(color);
});
return {
changeTheme,
};
}
在Vue组件中使用:
javascriptimport { useElementPlusTheme } from './theme';
export default {
setup() {
// 初始化主题色
const { changeTheme } = useElementPlusTheme('#409EFF');
// 动态修改主题色
const updateTheme = (newColor) => {
changeTheme(newColor);
};
return {
updateTheme
};
}
};
通过上述实现,我们可以:
这种实现方式的优点是:
缺点是:
这个解决方案适合需要动态主题切换的Element Plus项目,能够满足大多数定制化主题的需求。
本文作者:还是夸张一点
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!