网站主题切换

文章目录

  • 网站主题切换
    • 前言
    • 思路
      • 全部写在`style`属性中
      • 全部写在外部`css`文件中
        • 引用不同的`link`文件
        • 通过`class`命名空间的方式
        • `webpack`插件:`webpack-theme-color-replacer`
    • 实现
      • `webpack-theme-color-replacer`

网站主题切换

前言

关于网站主题的切换,其实也叫网站换肤。

记得以前博客流行的时代,换肤很受欢迎。也在那时候,就有想过这些事怎么实现的,不过那时的我还是名学生,也没有接触过网站的制作知识。

如今,我成了一名前端开发者,也工作的几年了,却一直没有接到过类似的需求,想来也奇怪。

但为了曾经的一点念想,用现在的知识来实现一下。

思路

颜色,肯定是通过css来显示的,但css有三种写法:

  1. style属性

  2. style标签

  3. 外部css文件

如果要实现网站的换肤效果,首先得统一与颜色相关的css的写法,在这里建议要么写在style属性中,要么写在外部css文件中

全部写在style属性中

思路:对于这中写法,我们可以在全局配置主题色变量,然后通过js代码将主题色写入对应标签的style属性中。当主题色发生变化的时候,通知修改所有相关的标签的style属性。

适用类型:适用于用vue这种双向数据绑定的项目,变量发生改变是自动更新视图。

优点:完全通过代码就可实现

缺点:对代码的要求高,只适用小项目,而且增加了代码的可维护性。

全部写在外部css文件中

有三种实现方式:

  1. 引用不同的link文件

  2. 通过class命名空间的方式

  3. webpack插件:webpack-theme-color-replacer

引用不同的link文件

思路:根据不同的主题,先写好对应的css文件。然后,在通过代码根据用户选择的主题,去加载对应的主题css文件。

适用类型:项目只需要几种固定的主题

优点:主题样式可以变化的空间很大

缺点:只能切换设计好的主题

通过class命名空间的方式

思路:根据不同的主题,设置对应的class命名空间。然后,在通过代码根据用户选择的主题,去切换对应的class。其实第一种方式有异曲同工之处。

适用类型:项目只需要几种固定的主题

优点:主题样式可以变化的空间很大

缺点:只能切换设计好的主题

webpack插件:webpack-theme-color-replacer

最近看到element-uiant-designiview的网站换肤功能都用到了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

第一步,安装插件

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属性上,切换时不会生效

你可能感兴趣的:(webpack)