# 方式一

# 安装 scss,参考文章:

vue 中引入 sass

# 具体实现

# 1、在 assets/styles 下新建.scss 文件,定义想要变化的颜色和主题。(只列举部分颜色)

// -------------------------------更换的系统主题颜色2(Standard)-----------------------------------//
// 菜单所有未选中文字样式
$menuTextStandard: #333333;
// 一级菜单样式
$menuBgStandard: #ffffff;
// 一级菜单鼠标悬浮
$menuHoverStandard: #f7f7f7;
// 一级菜单选中时文字样式
$subMenuActiveTextStandard: #82ba00;
// 选中背景:
$subMenuActiveBgStandard: #e6f1cc;
// -------------------------------更换的系统主题颜色3(StandardRed)-----------------------------------//
// 菜单所有未选中文字样式
$menuTextStandardRed: #333333;
// 一级菜单样式
$menuBgStandardRed: #ffffff;
// 一级菜单鼠标悬浮
$menuHoverStandardRed: #f7f7f7;
// 一级菜单选中时文字样式
$subMenuActiveTextStandardRed: #911844;
// 选中背景:
$subMenuActiveBgStandardRed: #e9d1da;
// -------------------------------更换的系统主题颜色4(StandardSkyBlue)-----------------------------------//
// 菜单所有未选中文字样式
$menuTextStandardSkyBlue: #333333;
// 一级菜单样式
$menuBgStandardSkyBlue: #ffffff;
// 一级菜单鼠标悬浮
$menuHoverStandardSkyBlue: #f7f7f7;
// 一级菜单选中时文字样式
$subMenuActiveTextStandardSkyBlue: #008299;
// 选中背景:
$subMenuActiveBgStandardSkyBlue: #cce6eb;

# 2、为需要切换的 5 个颜色在下面定义方法动态切换颜色:(注意部分样式要加 import 才会生效)

@mixin menuText($color) {
  color: $color;
  //   /* 判断匹配 */
  [data-theme="standard"] & {
    color: $menuTextStandard;
  }
  [data-theme="standardRed"] & {
    color: $menuTextStandardRed;
  }
  [data-theme="standardSkyBlue"] & {
    color: $menuTextStandardSkyBlue;
  }
}
@mixin menuBg($color) {
  background-color: $color !important;
  //   /* 判断匹配 */
  [data-theme="standard"] & {
    background-color: $menuBgStandard !important;
  }
  [data-theme="standardRed"] & {
    background-color: $menuBgStandardRed !important;
  }
  [data-theme="standardSkyBlue"] & {
    background-color: $menuBgStandardSkyBlue !important;
  }
}
@mixin menuHover($color) {
  background-color: $color;
  //   /* 判断匹配 */
  [data-theme="standard"] & {
    background-color: $menuHoverStandard;
  }
  [data-theme="standardRed"] & {
    background-color: $menuHoverStandardRed;
  }
  [data-theme="standardSkyBlue"] & {
    background-color: $menuHoverStandardSkyBlue;
  }
}
@mixin subMenuActiveText($color) {
  color: $color !important;
  //   /* 判断匹配 */
  [data-theme="standard"] & {
    color: $subMenuActiveTextStandard !important;
  }
  [data-theme="standardRed"] & {
    color: $subMenuActiveTextStandardRed !important;
  }
  [data-theme="standardSkyBlue"] & {
    color: $subMenuActiveTextStandardSkyBlue !important;
  }
}
@mixin subMenuActiveBg($color) {
  background-color: $color !important;
  //   /* 判断匹配 */
  [data-theme="standard"] & {
    background-color: $subMenuActiveBgStandard !important;
  }
  [data-theme="standardRed"] & {
    background-color: $subMenuActiveBgStandardRed !important;
  }
  [data-theme="standardSkyBlue"] & {
    background-color: $subMenuActiveBgStandardSkyBlue !important;
  }
}

# 3、在 main.js 中引入文件:

import './assets/styles/variables.scss'

# 4、在所有页面需要变色的颜色上使用:

//color:#f7f7f7  改为:
@include menuText();

# 5、App.vue 中一键全局更改主题颜色:

function setAttribute(theme) {
      window.document.documentElement.setAttribute("data-theme", theme);
 }
 setAttribute("standard");  // 应用主题 2 
 setAttribute("standardRed");  // 应用主题 3

# 方式二

# 根据预设的配色方案,在前端动态切换系统主题颜色

大概的思路就是给 html 根标签设置一个 data-theme 属性,然后通过 js 切换 data-theme 的属性值,Scss 根据此属性来判断使用对应主题变量。这里可以选择持久化 Vux 或接口来保存用户选择的主题。

# 具体实现

# 1、新建 themes.scss 文件

这里只是做示例就写两个样式参考,更多的自己补充一下

$themes: (
  Red: ( // 整体主色调 / 菜单栏背景 / 图标。按钮主色 / 悬停状态
    mainColor: #D6000F, // 主题色
    titleColor: #5f95cc, // 默认字体色 / 二级信息字体色
  ),
  Blue: ( // 整体主色调 / 菜单栏背景 / 图标。按钮主色 / 悬停状态
    mainColor: #409EFF, // 菜单选中背景色 / 点击状态 / 文字,按钮按下
    titleColor: #d64e18, // 列表背景色
  ),
);

# 2、新建 handle.scss 文件操作

themeify 方法用于获取 HTML 的 data-theme 值。
themed 方法用于根据 HTML 的 data-theme 值及调用者传过来的 key 去 themes.scss 里获取相应的颜色。

@import "./themes.scss";
// 切换主题时 获取不同的主题色值
@mixin themeify {
    @each $theme-name,
    $theme-map in $themes {
        //!global 把局部变量强升为全局变量
        $theme-map: $theme-map !global;
        // 判断 html 的 data-theme 的属性值  #{} 是 sass 的插值表达式
        //& sass 嵌套里的父容器标识   @content 是混合器插槽,像 vue 的 slot
        [data-theme="#{$theme-name}"] & {
            @content;
        }
    }
}
// 从主题色 map 中取出对应颜色
@function themed($key) {
    @return map-get($theme-map, $key);
}
// 获取背景颜色
@mixin background_color($color) {
    @include themeify {
        background-color: themed($color)!important;
    }
}
// 获取字体颜色
@mixin font_color($color) {
    @include themeify {
        color: themed($color)!important;
    }
}

# 3、在 vue 页面中使用

<template>
  <div class="my--demo">
      <Dropdown>
        <Button type="primary">
         主题切换
          <i class="el-icon-arrow-down el-icon--right"></i>
        </Button>
        <DropdownMenu slot="dropdown">
          <DropdownItem @click.native="theme('normal')">默认</DropdownItem>
          <DropdownItem @click.native="theme('Red')">红色</DropdownItem>
          <DropdownItem @click.native="theme('Blue')">蓝色</DropdownItem>
        </DropdownMenu>
      </Dropdown>
      <div class="common-util">测试主题变化</div>
  </div>
</template>
<script>
export default {
  name: 'themeDemo',
  methods: {
    // 换主题
    theme(type) {
      window.document.documentElement.setAttribute('data-theme', type)
    },
  },
}
</script>
<style lang="scss" scoped>
@import '@/styles/base/_handle.scss';
.common-util {
  font-size: 18px;
  height: 100px;
  margin-top: 20px;
  @include font_color('titleColor');
  @include background_color('mainColor');
  @include border_color('mainColor');
}
</style>