Element-ui
是前端日常开发中比较常用的UI库,提供了很多组件给我们使用,但是很多时候我们UI设计稿的颜色和 Element-ui
的不一致, 今天我们来说一下如何去修改 Element-ui
的主题色以及如何实时更新主题色的一键修改主题
其实关于 Element-ui
的修改主题色官方是有介绍的, 点击查看官方说明:
- 可以通过官方在线主题修改工具生成主题下载好文件后放入项目, 不再引入原先的css, 而是引入新的 css
// import 'element-ui/lib/theme-chalk/index.css'
import '../theme/index.css'
- 如果你的项目使用了
scss
,那么可以直接新建一个element-ui
文件在main.js
中引入即可, 推荐使用这种方式, 方便在项目中随时修改
/* 改变主题色变量 */
$--color-primary: red;
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
如果有确认的主题色还是比较简单的, 接下来解释一下如何实现一键换肤这种实时更换主题色,首先扔一个实现好的js, 该js实现了如何实时修改 element-ui
的主题色
const version = require('element-ui/package.json').version // 版本号
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
const ORIGINAL_THEME = '#409EFF' // element-ui 默认的颜色
export default class ThemeColor {
constructor(defalutColor) {
const theme = defalutColor || ORIGINAL_THEME
this.changeThemeColor(theme)
}
// 判断是否为颜色
isColorValue(bgVal) {
if (bgVal) {
let type = '^#[0-9a-fA-F]{6}$'
let re = new RegExp(type)
if (bgVal.match(re) == null) {
type =
'^[rR][gG][Bb][(]([\\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\\s]*,){2}[\\s]*(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)[\\s]*[)]{1}$'
re = new RegExp(type)
if (bgVal.match(re) == null) {
return false
} else {
return true
}
} else {
return true
}
}
}
// 更新主题色
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
}
// 改变颜色
changeThemeColor(colorValue) {
if (this.isColorValue(colorValue)) {
const themeCluster = this.getThemeCluster(colorValue.replace('#', ''))
const originalCluster = this.getThemeCluster(
ORIGINAL_THEME.replace('#', '')
)
const getHandler = (variable, id) => {
return () => {
const newStyle = this.updateStyle(
this[variable],
originalCluster,
themeCluster
)
let styleTag = document.getElementById(id)
// 判断是否已经存在标签,没有则生成
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
// 替换为新的样式表
styleTag.innerText = newStyle
}
}
const chalkHandler = getHandler('chalk', 'chalk-style')
// 判断是否已有样式表,没有则根据url请求样式表内容
if (!this.chalk) {
this.getCSSString(url, chalkHandler, 'chalk')
} else {
chalkHandler()
}
const styleDom = document.getElementsByTagName('body')[0].style
styleDom.setProperty('--theme', colorValue)
} else {
console.error('改变主题色出错, 得到的值并不是一个合法的颜色值')
}
}
// 初始化时获取默认主题的样式并复制给this.chalk
getCSSString(url, callback, variable) {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
callback()
}
}
xhr.open('GET', url)
xhr.send()
}
// 获取系列色
getThemeCluster(theme) {
const formatColor = (color) => {
const str = color.toString(16)
return str.length === 2 ? str : '0' + str
}
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) {
return [red, green, blue].join(',')
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red = formatColor(red)
green = formatColor(green)
blue = formatColor(blue)
return `#${red}${green}${blue}`
}
}
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = formatColor(red)
green = formatColor(green)
blue = formatColor(blue)
return `#${red}${green}${blue}`
}
const clusters = [theme]
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
return clusters
}
}
这是用法
const ThemeUI = new ThemeColor('#409EFF')
setTimeout(() => {
// 改变主题色
ThemeUI.changeThemeColor('#e50011')
}, 3000)
在修改了 Element-ui
的主题色后,我们还需要修改我们自己使用的一些变量,scss
中我们定义变量时用下面的方式定义
$--theme-color: var(--theme, #409EFF);
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
baseColor: $--theme-color;
}
--theme
这是个key, 使用 --
开头, 接下来我们修改这个变量
const styleDom = document.getElementsByTagName('body')[0].style
styleDom.setProperty('--theme', '#e50011')
这样我们scss
定义的变量也可以修改了, 我们在写项目的时候把需要变色的变量通过scss
定义,这样就可以实现项目的一键换肤了