基于ele+vue开发切换主题颜色,ele自带不够完成业务开发故而研究sass补充开发
前言
基于ele+vue开发切换主题颜色,ele自带不够完成业务开发故而研究sass补充开发
提示:仅展示sass部分代码:
一、创建切换按钮?
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
二、使用步骤
1.引入库
代码如下(示例) el-dropdown循环切换:
<el-dropdown trigger="click">
<span class="el-dropdown-link">
主题
<i class="el-icon-arrow-down el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="item in Object.keys(themeList)"
@click.native="themeFn(themeList[item].value, themeList[item].color)"
:key="item"
>
<i :style="{ background: themeList[item].color }" class="colors"></i>
{{ themeList[item].label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
不理解可看ele官方文档
themeList为数组
themeList:[
0: { label: '默认', value: 'Construction', color: '#0066C5' },
1: { label: '建设银行', value: 'Construction', color: '#0066C5' },
2: { label: '中国银行', value: 'China', color: '#B50029' },
3: { label: '交通银行', value: 'Its', color: '#00377A' },
4: { label: '农业银行', value: 'NY', color: '#319C8B' },
5: { label: '工商银行', value: 'GS', color: '#C7000A' },
6: { label: '邮政银行', value: 'EMS', color: '#086547' }]
watch: { // data中定义变量theme
async theme(val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
this.$message({
message: ' 切换主题色中',
customClass: 'theme-message',
type: 'success',
duration: 1500,
iconClass: 'el-icon-loading'
})
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(
ORIGINAL_THEME.replace('#', '')
)
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
}
}
if (!this.chalk) {
await this.getCSSString('chalk')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
// 更改其他 style 标签 中的颜色
// 但是需要刷新才能生效
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.changeTheme(themeCluster)
this.$emit('change', val)
for (let i = 0; i < Object.values(themeList).length; i++) {
if (
Object.values(themeList)[i].color ==
(val.indexOf('#') > 0 ? '#' + val : val)
) {
this.themeFn(
Object.values(themeList)[i].value,
Object.values(themeList)[i].color
)
}
}
}
},
themeFn(value, color) { //为函数
this.$nextTick().then(() => {
if (this.theme != color && color != undefined && color != null) {
this.theme = color
}
})
if (color) {
window.document.documentElement.setAttribute('data-theme', value)
} else {
for (let i = 0; i < Object.values(themeList).length; i++) {
if (
Object.values(themeList)[i].color ==
(this.theme.indexOf('#') != -1 ? this.theme : '#' + this.theme)
) {
window.document.documentElement.setAttribute(
'data-theme',
Object.values(themeList)[i].value
)
}
}
}
},
大概思路为在app的上面添加一个class 在切换过程中原生更改class来控制
sass部分截屏显示好了
创建按钮点击后给标签添加data-theme根据传递的参数来选定主题
var.scss中定义四种变量对应不同变量的背景颜色及字体颜色
定义整体样式表中重复使用样式 其中为判断点击事件传递的参数来给予对应背景
页面中将 所有使用 $–color-primary 的变量值都换成对应背景颜色及字体
仅为自己开发回顾使用 仅提供思路 仿照可能会会报错哦
<template>
<div>
<el-dropdown trigger="click">
<span class="el-dropdown-link">
主题
<i class="el-icon-arrow-down el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="item in Object.keys(themeList)"
@click.native="themeFn(themeList[item].value, themeList[item].color)"
:key="item"
>
<i :style="{ background: themeList[item].color }" class="colors"></i>
{{ themeList[item].label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<script>
// import axios from 'axios'
import { themeList } from '@/lib/map'
import { mapActions, mapGetters } from 'vuex'
import { getThemeScript } from '@/api/common/common.js'
import { ORIGINAL_THEME } from '@/lib/constant'
export default {
data() {
return {
themeList,
theme: '',
chalk: '' // content of theme-chalk css
}
},
computed: {
...mapGetters(['themeColor']) // 当前主题色
},
watch: {
async theme(val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
this.$message({
message: ' 切换主题色中',
customClass: 'theme-message',
type: 'success',
duration: 1500,
iconClass: 'el-icon-loading'
})
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(
ORIGINAL_THEME.replace('#', '')
)
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
}
}
if (!this.chalk) {
await this.getCSSString('chalk')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
// 更改其他 style 标签 中的颜色
// 但是需要刷新才能生效
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.changeTheme(themeCluster)
this.$emit('change', val)
for (let i = 0; i < Object.values(themeList).length; i++) {
if (
Object.values(themeList)[i].color ==
(val.indexOf('#') > 0 ? '#' + val : val)
) {
this.themeFn(
Object.values(themeList)[i].value,
Object.values(themeList)[i].color
)
}
}
}
},
created() {
this.theme = this.themeColor ?? ''
this.themeFn()
},
methods: {
...mapActions('setting', ['changeTheme']),
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
},
async getCSSString(variable) {
try {
this[variable] = await getThemeScript()
} catch (e) {}
},
themeFn(value, color) {
this.$nextTick().then(() => {
if (this.theme != color && color != undefined && color != null) {
this.theme = color
}
})
if (color) {
window.document.documentElement.setAttribute('data-theme', value)
} else {
for (let i = 0; i < Object.values(themeList).length; i++) {
if (
Object.values(themeList)[i].color ==
(this.theme.indexOf('#') != -1 ? this.theme : '#' + this.theme)
) {
window.document.documentElement.setAttribute(
'data-theme',
Object.values(themeList)[i].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
}
}
// methods: {
// }
}
</script>
<style lang="scss">
.theme-message,
.theme-picker-dropdown {
z-index: 99999 !important;
}
.theme-picker .el-color-picker__trigger {
height: 26px !important;
width: 26px !important;
padding: 2px;
}
.theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
}
.el-dropdown-menu__item .colors {
display: inline-block;
vertical-align: middle;
width: 10px;
height: 10px;
border-radius: 50%;
}
</style>
// 切换字体样式
@import './variables.scss';
@import './var.scss';
/* 自定义主题 借鉴var.scss定义变量 */
// 建设银行 #0066C5
$colors-Construction: (
color-primary: #0066C5, // 背景
menu-color: #0066C5, //字体颜色
rgba-bg-color:rgba(0,102,197,.1),
white-color: #ffffff,
);
// 中国银行 #B50029
$colors-China: (
color-primary: #B50029,
menu-color: #B50029,
rgba-bg-color:rgba(181,0,41,.1),
white-color: #ffffff,
);
// 交通银行 #00377A
$colors-Its: (
color-primary: #00377A,
menu-color: #00377A,
rgba-bg-color:rgba(0,55,122,.1),
white-color: #ffffff,
);
// 农业银行 #319C8B
$colors-NY: (
color-primary: #319C8B,
menu-color: #319C8B,
rgba-bg-color:rgba(49,156,139,.1),
white-color: #ffffff,
);
// 工商银行
$colors-GS: (
color-primary: #C7000A,
menu-color: #C7000A,
rgba-bg-color:rgba(199,0,10,.1),
white-color: #ffffff,
);
// 邮政银行
$colors-EMS: (
color-primary: #086547,
menu-color: #086547,
rgba-bg-color:rgba(8,101,71,.1),
white-color: #ffffff,
);
// 切换字体样式
// @import './variables.scss';
@import './var.scss';
// 切换模态框的背景色
/*
参数介绍
changeBgColor -- 常用更改背景及字体颜色
changeButton -- 常用按钮更改背景字体边框
changeColor -- 常用更改字体颜色
changeTabsItem -- 常用更改标题栏
*/
@mixin changeBgColor($key) {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-Construction, $key) !important;
[data-theme="Construction"] & {
transition: border-color 0.1s, background-color 0.1s, color 0.1s;
background: map-get($colors-Construction, $key) !important;
border: none;
}
// 中国银行
[data-theme="China"] & {
transition: border-color 0.1s, background-color 0.1s, color 0.1s;
background: map-get($colors-China, $key) !important;
border: none;
}
// 交通银行
[data-theme="Its"] & {
transition: border-color 0.1s, background-color 0.1s, color 0.1s;
background: map-get($colors-Its, $key) !important; border: none;
}
// 农业银行
[data-theme="NY"] & {
transition: border-color 0.1s, background-color 0.1s, color 0.1s;
background: map-get($colors-NY, $key) !important; border: none;
}
// 工商银行
[data-theme="GS"] & {
transition: border-color 0.1s, background-color 0.1s, color 0.1s;
background: map-get($colors-GS, $key) !important; border: none;
}
// 邮政银行
[data-theme="EMS"] & {
transition: border-color 0.1s, background-color 0.1s, color 0.1s;
background: map-get($colors-EMS, $key) !important; border: none;
}
}
@mixin changeButton($key) {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-Construction, $key) !important;
color: #fff;
border: 1px solid map-get($colors-Construction, $key);
[data-theme="Construction"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-Construction, $key) !important;
color: #fff;
border: 1px solid map-get($colors-Construction, $key);
}
// 中国银行
[data-theme="China"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-China, $key) !important;
color: #fff;
border: 1px solid map-get($colors-China, $key);
}
// 交通银行
[data-theme="Its"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-Its, $key) !important;
color: #fff;
border: 1px solid map-get($colors-Its, $key);
}
// 农业银行
[data-theme="NY"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-NY, $key) !important;
color: #fff;
border: 1px solid map-get($colors-NY, $key);
}
// 工商银行
[data-theme="GS"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-GS, $key) !important;
color: #fff;
border: 1px solid map-get($colors-GS, $key);
}
// 邮政银行
[data-theme="EMS"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-EMS, $key) !important;
color: #fff;
border: 1px solid map-get($colors-EMS, $key);
}
}
@mixin changeColor($key) {
color: map-get($colors-Construction, $key) !important;
[data-theme="Construction"] & {
color: map-get($colors-Construction, $key) !important;
}
// 中国银行
[data-theme="China"] & {
color: map-get($colors-China, $key) !important;
}
// 交通银行
[data-theme="Its"] & {
color: map-get($colors-Its, $key) !important;
}
// 农业银行
[data-theme="NY"] & {
color: map-get($colors-NY, $key) !important;
}
// 工商银行
[data-theme="GS"] & {
color: map-get($colors-GS, $key) !important;
}
// 邮政银行
[data-theme="EMS"] & {
color: map-get($colors-EMS, $key) !important;
}
}
@mixin changeTabsItem($key) {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-Construction, $key) !important;
color: #fff;
border: 1px solid map-get($colors-Construction, $key);
[data-theme="Construction"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-Construction, $key) !important;
color: #fff;
border: 1px solid map-get($colors-Construction, $key);
}
// 中国银行
[data-theme="China"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-China, $key) !important;
color: #fff;
border: 1px solid map-get($colors-China, $key);
}
// 交通银行
[data-theme="Its"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-Its, $key) !important;
color: #fff;
border: 1px solid map-get($colors-Its, $key);
}
// 农业银行
[data-theme="NY"] & {
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
background: map-get($colors-NY, $key) !important;
color: #fff;
border: 1px solid map-get($colors-NY, $key);
}
}
@mixin changeBorder($key) {
border: 1px solid map-get($colors-Construction, $key);
color:map-get($colors-Construction, $key) ;
[data-theme="Construction"] & {
border: 1px solid map-get($colors-Construction, $key);
color:map-get($colors-Construction, $key) ;
}
// 中国银行
[data-theme="China"] & {
color:map-get($colors-China, $key) ;
border: 1px solid map-get($colors-China, $key);
}
// 交通银行
[data-theme="Its"] & {
color:map-get($colors-Its, $key) ;
border: 1px solid map-get($colors-Its, $key);
}
}
借鉴:Sass应用之实现主题切换