文章目录
网站主题切换
前言
关于网站主题的切换,其实也叫网站换肤。
记得以前博客流行的时代,换肤很受欢迎。也在那时候,就有想过这些事怎么实现的,不过那时的我还是名学生,也没有接触过网站的制作知识。
如今,我成了一名前端开发者,也工作的几年了,却一直没有接到过类似的需求,想来也奇怪。
但为了曾经的一点念想,用现在的知识来实现一下。
思路
颜色,肯定是通过
css
来显示的,但
css
有三种写法:
-
style
属性 -
style
标签 -
外部
css
文件
如果要实现网站的换肤效果,首先得统一与颜色相关的
css
的写法,在这里建议要么写在style属性中,要么写在外部
css
文件中
全部写在
style
属性中
style
思路:对于这中写法,我们可以在全局配置主题色变量,然后通过
js
代码将主题色写入对应标签的
style
属性中。当主题色发生变化的时候,通知修改所有相关的标签的
style
属性。
适用类型:适用于用
vue
这种双向数据绑定的项目,变量发生改变是自动更新视图。
优点:完全通过代码就可实现
缺点:对代码的要求高,只适用小项目,而且增加了代码的可维护性。
全部写在外部
css
文件中
css
有三种实现方式:
-
引用不同的
link
文件 -
通过
class
命名空间的方式 -
webpack
插件:
webpack-theme-color-replacer
引用不同的
link
文件
link
思路:根据不同的主题,先写好对应的
css
文件。然后,在通过代码根据用户选择的主题,去加载对应的主题
css
文件。
适用类型:项目只需要几种固定的主题
优点:主题样式可以变化的空间很大
缺点:只能切换设计好的主题
通过
class
命名空间的方式
class
思路:根据不同的主题,设置对应的class命名空间。然后,在通过代码根据用户选择的主题,去切换对应的class。其实第一种方式有异曲同工之处。
适用类型:项目只需要几种固定的主题
优点:主题样式可以变化的空间很大
缺点:只能切换设计好的主题
webpack
插件:
webpack-theme-color-replacer
webpack
webpack-theme-color-replacer
最近看到
element-ui
、
ant-design
、
iview
的网站换肤功能都用到了
webpack-theme-color-replacer
,发现这是目前最好的一种网站主题色切换方式。
思路:
webpack-theme-color-replacer
的思路是先通过
webpack
打包时,将主题色的颜色值与
css
文件进行匹配,提取匹配到的
css
样式单独生成一个
theme-color.css
。
当用户修改主题色时,先读取
theme-color.css
中的内容并将主题色进行替换,最后在再将样式写入到
html
文件中的
style
标签中,从而实现了主题切换。
适用类型:中后台系统,主题色的颜色按照淡化的方式变化
优点:可以随意切换主题色
缺点:主题色的颜色按照淡化的方式变化
实现
在这里只实现利用
webpack
插件:
webpack-theme-color-replacer
这一种方法,其他方法网上有很多例子。
webpack-theme-color-replacer
webpack-theme-color-replacer
第一步,安装插件
npm i -D webpack-theme-color-replacer
第二步,配置
webpack
const WebpackThemeColorReplacer = require('webpack-theme-color-replacer')
new WebpackThemeColorReplacer({
fileName: 'css/theme-colors-[contenthash:8].css',
// 根据匹配的css样式生成单独的css文件
matchColors: [
...forElementUI.getElementUISeries('#FF0000'),
// 根据主题色生成一系列颜色(10个),适用于ElementUI、Ani Design、Iview等组件
'#FF0000'
// 自定义的主题色
],
// 需要匹配的网站主题色
resolveCss(resultCss) {
return resultCss.replace(/#4b0/g, '#ed4040')
},
// 将匹配的颜色值替换
externalCssFiles: [],
// 外部css文件,比如引用了第三方的css文件
changeSelector(cssSelector) {
return cssSelector
},
isJsUgly: process.env.NODE_ENV !== 'development'
// 压缩生成的css文件
})
第三步,项目加入切换代码
import replacer from 'webpack-theme-color-replacer/client'
// 引入插件方法
function changeColor(newColor) {
var options = {
newColors: [...forElementUI.getElementUISeries(newColor), newColor],
// 传入的新的主题色
changeUrl(cssUrl) {
return `/${cssUrl}`
}
// 如果需要加载自定义的css文件
// 这种方式就像加载外部link一样
}
replacer.changer.changeColor(options, Promise).then(() => {
console.log('Theme colors changed!')
})
// 执行切换主题方法,返回promise
}
changeColor('#FF3333')
// 用户切换主题色时触发切换方法
所有的主题色相关的
css
样式都需要写在
css
外部文件中,如果写在了
style
属性上,切换时不会生效