基于vue-element-admin的换肤功能
vue-element-admin
PanJiaChen/vue-element-admin: 是一个基于 Vue.js 和 Element UI 的后台管理系统模板,支持多种数据源和插件扩展。该项目提供了一个完整的后台管理系统模板,可以方便地实现后台管理系统的快速搭建和定制,同时支持多种数据源和插件扩展。
项目地址:https://gitcode.com/gh_mirrors/vu/vue-element-admin
免费下载资源
·
基于vue-element-admin的换肤功能
一、封装ThemePicker主题颜色选择组件
使用elementUI组件库自带的colorPicker组件来获取颜色
<template>
<el-color-picker
v-model="theme"
:predefine="[
'#409EFF',
'#1890ff',
'#304156',
'#212121',
'#11a983',
'#13c2c2',
'#6959CD',
'#f5222d'
]"
class="theme-picker"
popper-class="theme-picker-dropdown"
/>
</template>
二、初始化变量文件
创建element-variable.scss文件,在这个文件中,内部包含了主题所用到的变量,通过设置变量的值,可以直接个性化设置element组件的颜色主题。在这里我们将$–color-primary的值向外暴露,供后续修改。
// element-variable.scss
$--color-primary: #00cec9;
$--color-success: #13ce66;
$--color-warning: #ffba00;
$--color-danger: #ff4949;
$--button-font-weight: 400;
$--border-color-light: #dfe4ed;
$--border-color-lighter: #e6ebf5;
$--table-border: 1px solid #dfe6ec;
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import '~element-ui/packages/theme-chalk/src/index';
:export {
theme: $--color-primary;
}
三、在vuex和localStorage中保存主题颜色并封装修改主题颜色的mutation和action
创建element-variable.scss文件,在这个文件中,内部包含了主题所用到的变量,通过设置变量的值,可以直接个性化设置element组件的颜色主题。在这里我们将$–color-primary的值向外暴露,供后续修改。
import variables from '@/styles/element-variables.scss'
const { tabShow } = defaultSettings
const THEME_KEY = 'theme'
const state = {
theme: localStorage.getItem(THEME_KEY) || variables.theme
}
const mutations = {
CHANGE_SETTING: (state, { key, value }) => {
// eslint-disable-next-line no-prototype-builtins
if (state.hasOwnProperty(key)) {
state[key] = value
if (key === 'theme') {
localStorage.setItem(THEME_KEY, value)
}
}
}
}
const actions = {
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
四、将实现更新element组件颜色的方法封装到混入中
由于在不单单只是点击ThemePicker组件时要更换颜色,当本地localStorage中保存有theme时,也要展示为保存的主题颜色,因此我们要将设置主题颜色的方法封装到混入中。
export default {
data() {
return {
version: require('element-ui/package.json').version,
ORIGINAL_THEME: '#409EFF' // 默认颜色
}
},
methods: {
async updateTheme(val) {
const oldVal = this.chalk ? this.theme : this.ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
// console.log(themeCluster, originalCluster)
const $message = this.$message({
message: ' Compiling the theme',
customClass: 'theme-message',
type: 'success',
duration: 0,
iconClass: 'el-icon-loading'
})
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(
this.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) {
const url = `https://unpkg.com/element-ui@${this.version}/lib/theme-chalk/index.css`
await this.getCSSString(url, 'chalk')
}
const chalkHandler = getHandler('chalk', '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.$emit('change', val)
$message.close()
},
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
},
getCSSString(url, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
}
xhr.open('GET', url)
xhr.send()
})
},
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
}
}
}
五、ThemePicker中设置主题颜色
监听theme值,将最新的主题颜色保存到保存到vuex和localStorage中,调用混入的updateTheme更新主题颜色方法,并传入最新的颜色。
<script>
import themeMixin from '@/mixin/updateTheme'
export default {
name: 'ThemePicker',
mixins: [themeMixin],
data() {
return {
theme: ''
}
},
computed: {
defaultTheme() {
return this.$store.state.settings.theme
}
},
watch: {
defaultTheme: {
handler: function(val, oldVal) {
this.theme = val
},
immediate: true
},
async theme(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'theme',
value: val
})
this.updateTheme(val)
}
}
}
</script>
六、使用本地保存的主题颜色
mixins: [themeMixin],
async created() {
if (localStorage.getItem('theme')) {
this.$store.dispatch('settings/changeSetting', {
key: 'theme',
value: localStorage.getItem('theme')
})
const val = localStorage.getItem('theme')
this.updateTheme(val)
}
}
GitHub 加速计划 / vu / vue-element-admin
87.26 K
30.42 K
下载
PanJiaChen/vue-element-admin: 是一个基于 Vue.js 和 Element UI 的后台管理系统模板,支持多种数据源和插件扩展。该项目提供了一个完整的后台管理系统模板,可以方便地实现后台管理系统的快速搭建和定制,同时支持多种数据源和插件扩展。
最近提交(Master分支:26 天前 )
0caa975e - 2 年前
cd3f7267 - 2 年前
更多推荐
已为社区贡献1条内容
所有评论(0)