使用css自定义变量实现实现主题切换功能

前言

之前,写过一篇基于less自定义函数实现主题切换功能

此种方法缺陷:

  • 从原本的项目中抽离样式比较繁琐;
  • 自定义函数传参方式,可读性比较差,容易造成传参混淆;
  • 因为主题自定义函数中定义的类是共用的,如果不同组件中类重名了,会影响到每个组件;需要在自定义函数中定义一个唯一命名的类,然后在需要使用该主题样式的地方进行引入;这无形中又增加了切换主题的复杂度;

所以上篇文章最后提到的关于切换css变量的方式,个人觉得,还是简介明了。所以接下来就介绍一下 使用css自定义变量实现实现主题切换功能

实现步骤

1. 切换主题,为body添加不同类名

<template>
  <div>
    <Select v-model="theme" @on-change="changeTheme">
      <Option v-for="item in themes" :value="item.value" :key="item.value">{{ item.name }}</Option>
    </Select>
  </div>
</template>

<script>
export default {
  data() {
    return {
      themes: [
        { name: '白色主题', value: 'theme-light' },
        { name: '黑色主题', value: 'theme-dark' },
      ],
      theme: '',
    };
  },
  methods: {
    changeTheme(theme) {
      window.localStorage.setItem('theme', theme);
      // 设置body类
      const body = document.querySelector('body');
      this.themes.forEach((t) => {
        body.classList.remove(t.value);
      });
      body.classList.add(theme);
    },
  },
  created() {
    // 初始化获取主题
    this.theme = window.localStorage.getItem('theme') || this.themes[0].value;
    // 设置body类
    const body = document.querySelector('body');
    body.classList.add(this.theme);
  },
};
</script>

2. 针对不同类名,为css自定义变量赋值

比如theme-light.less中

.theme-light {
      --color: #fff;
}

theme-dark.less中

.theme-dark {
      --color: #000;
}

3. 项目中引入保存主题变量的less文件

@import "~@/styles/theme/theme-light.less";
@import "~@/styles/theme/theme-dark.less";

4. 使用css自定义变量

.header{
     color: var(--color); 
}

综上,整体思路:切换主题时,为body赋值不同类,每个类下为css变量赋不同颜色值;