今天尝试在项目中完成切换主题的功能,目前已经实现,故做个记录
- 新建一个 scss 文件保存颜色配置,例如:
 
// themes.scss
$themes: (
  light: (
    main: #364f6b,
    second: #3fc1c9,
    third: #f5f5f5,
    fourth: #fc5185,
  ),
  dark: (
    main: #e4f9f5,
    second: #30e3ca,
    third: #11999e,
    fourth: #40514e,
  ),
);
- 新建另一个 scss 文件,创建 mixin:
 
// themify.scss
@import "./themes.scss";
@mixin themify($themes: $themes) {
  @each $theme, $map in $themes {
    :global(.theme-#{$theme}) & {
      $theme-map: () !global;
      @each $key, $submap in $map {
        $value: map-get(map-get($themes, $theme), "#{$key}");
        $theme-map: map-merge(
          $theme-map,
          (
            $key: $value,
          )
        ) !global;
      }
      @content;
      $theme-map: null !global;
    }
  }
}
@function themed($key) {
  @return map-get($theme-map, $key);
}
- 使用:
 
@import "../../assets/styles/themify.scss";
.header {
  width: 100%;
  height: 60px;
  padding: 0 20px;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  @include themify {
    background-color: themed("main");
    color: themed("third");
  }
}
- 最后:
 
import React, { useState } from "react";
import styles from "./app.module.scss";
import classNames from "classnames";
import { Header } from "./components/header";
enum Themes {
  Light = "light",
  Dark = "dark",
}
function App() {
  const [theme, setTheme] = useState<Themes>(Themes.Light);
  function toggleTheme() {
    setTheme(theme === Themes.Light ? Themes.Dark : Themes.Light);
  }
  return (
    <div className={classNames(styles.app, `theme-${theme}`)}>
      <Header toogleTheme={toggleTheme} />
    </div>
  );
}
export default App;