Vue 换肤的示例实践

2020-06-16 06:06:05易采站长站整理

最近公司做的项目得到一个网站换肤的需求,也就是切换主题。那么如何切换主题色呢?切换主题色其实就是切换 CSS,然而在项目中不仅只有 CSS 需要换肤,图标和图片也需要跟随主题进行切换。于是,写一篇文章来记录下 Vue 中实现换肤的过程,先看下效果吧。

本文主要分三部分:CSS 切换,图标切换和图片切换。

CSS切换

关于 CSS 颜色的切换,我通过搜索,参考了ElementUI 的方案,总的来说分为四步

在 static 目录下新建一个 theme.css 文件,将需要替换的 CSS 声明在此文件中


.side-bar {
background: linear-gradient(#B7A3FF, #879FFF) !important;
}

.side-bar .account-info {
background: #8981D8 !important;
}

声明所有可选的主题,每种颜色都对应于一个关键词,方便区分


colors: [{
themeId: 1,
familyPrimary: '#B7A3FF',
familySecondary: '#879FFF',
sideBarTop: '#8981D8'
}, {
themeId: 2,
familyPrimary: '#FDC5C5',
familySecondary: '#F070A0',
sideBarTop: '#E7829F'
}, {
themeId: 3,
familyPrimary: '#414D6C',
familySecondary: '#2D1E3C',
sideBarTop: '#423C50'
}]

通过 AJAX 获取 theme.css ,将颜色值替换为关键词。


getFile(`/static/theme.css`)
.then(({data}) => {
let style = getStyleTemplate(data)
})

function getStyleTemplate (data) {
const colorMap = {
'#B7A3FF': 'familyPrimary',
'#879FFF': 'familySecondary',
'#8981D8': 'sideBarTop'
}
Object.keys(colorMap).forEach(key => {
const value = colorMap[key] data = data.replace(new RegExp(key, 'ig'), value)
})
return data
}

把关键词再换回刚刚生成的相应的颜色值,并在页面上添加 style 标签


getFile(`/static/theme.css`)
.then(({data}) => {
let style = getStyleTemplate(data)
writeNewStyle(style, this.color)
})

function writeNewStyle (originalStyle, colors) {
let oldEl = document.getElementById('temp-style')
let cssText = originalStyle
Object.keys(colors).forEach(key => {
cssText = cssText.replace(new RegExp(key, 'ig'), colors[key])
})
const style = document.createElement('style')
style.innerText = cssText
style.id = 'temp-style'
oldEl ? document.head.replaceChild(style, oldEl) : document.head.appendChild(style)
}

图标切换

由于项目刚开始做的时候并没有考虑到换肤的需求,于是所有图标都是采用 img 标签的方式引用的,