今天给大家分享一下在Vue中使用ElementUI时,想切换主题颜色的两种方式。

第一种:静态改变项目中的主题颜色

比较简单,稍微带过: 项目中创建element-variables.scss文件,编写内容:

/* 改变主题色变量 */

$--color-primary: teal;

/* 改变 icon 字体路径变量,必需 */

$--font-path: '~element-ui/lib/theme-chalk/fonts';

@import "~element-ui/packages/theme-chalk/src/index";

之后,在项目的入口文件中,直接引入以上样式文件即可(无需引入 Element 编译好的 CSS 文件)

import Vue from 'vue'

import Element from 'element-ui'

import './element-variables.scss'

Vue.use(Element)

第二种:重点!!!动态切换主题颜色并做缓存

创建theme.js文件,作为工具类,并写入以下内容:

const __DEFUALT__COLOR = "#409EFF"

const version = require('element-ui/package.json').version

class Theme {

constructor() {

const color = this._getLocalTheme() || __DEFUALT__COLOR;

const oldVal = this._getLocalTheme() || __DEFUALT__COLOR;

this.changeTheme(color, oldVal);

this.chalk = ''

}

async changeTheme($color, oldVal) {

const themeCluster = this._getThemeCluster($color.replace('#', ''))

const originalCluster = this._getThemeCluster(oldVal.replace('#', ''))

const getHandler = (id) => {

return () => {

const originalCluster = this._getThemeCluster(__DEFUALT__COLOR.replace('#', ''))

const newStyle = this._updateStyle(this.chalk, originalCluster, themeCluster)

let styleTag = document.getElementById(id)

if (!styleTag) {

styleTag = document.createElement('style')

styleTag.setAttribute('id', id)

document.head.appendChild(styleTag)

}

styleTag.innerText = newStyle

}

}

if (!this.chalk) {

const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`

await this._getCSSString(url, 'chalk')

}

const chalkHandler = getHandler('chalk-style')

chalkHandler()

const styles = [].slice.call(document.querySelectorAll('style'))

.filter(style => {

const text = style.innerText

return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)

})

styles.forEach(style => {

const { innerText } = style

if (typeof innerText !== 'string') return

style.innerText = this._updateStyle(innerText, originalCluster, themeCluster)

})

this._setLocalTheme("--primary-color", $color)

}

_getLocalTheme(key = "--primary-color") {

return key && localStorage.getItem(key);

}

_setLocalTheme(key, value) {

localStorage[key] = value;

}

_getThemeCluster(theme) {

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) { // when primary color is in its rgb space

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 = red.toString(16)

green = green.toString(16)

blue = blue.toString(16)

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 = red.toString(16)

green = green.toString(16)

blue = blue.toString(16)

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

}

_updateStyle(style, oldCluster, newCluster) {

let newStyle = style

oldCluster.forEach((color, index) => {

newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])

})

return newStyle

}

_getCSSString(url) {

return new Promise(resolve => {

const xhr = new XMLHttpRequest()

xhr.onreadystatechange = () => {

if (xhr.readyState === 4 && xhr.status === 200) {

this.chalk = xhr.responseText.replace(/@font-face{[^}]+}/, '')

resolve()

}

}

xhr.open('GET', url)

xhr.send()

})

}

}

export default Theme

然后在项目入口main.js中引入即可

import Vue from 'vue'

import Theme from "./utils/theme

Vue.prototype.$theme = new Theme()

在ThemePicker中使用

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: