@emotion/css + react+动态主题切换

1.下载插件

npm install --save @emotion/css

2.创建ThemeContext.tsx

// src/ThemeContext.tsx
import React, { createContext, useContext, useState } from "react";

// 定义主题类型
export type Theme = "light" | "dark";

// 定义主题上下文的类型
interface ThemeContextType {
  theme: Theme;
  toggleTheme: () => void;
}

// 创建主题上下文
export const ThemeContext = createContext<ThemeContextType | undefined>(undefined);

// 创建一个主题提供器组件
export const ThemeProvider: React.FC = ({ children }) => {
  const [theme, setTheme] = useState<Theme>("light"); // 默认主题为 'light'

  const toggleTheme = () => {
    setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
  };

  return <ThemeContext.Provider value={{ theme, toggleTheme }}>{children}</ThemeContext.Provider>;
};

// 创建一个自定义钩子来方便使用主题上下文
export const useTheme = () => {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error("useTheme must be used within a ThemeProvider");
  }
  return context;
};

3.创建themeConfig.ts配置主题颜色文件

//themeConfig.ts
import { Theme } from "./ThemeContext";

export const themes = {
  light: {
    backgroundColor: "#ffffff",
    color: "green",
    primaryColor: "#007bff",
    secondaryColor: "#6c757d",
  },
  dark: {
    backgroundColor: "#333333",
    color: "red",
    primaryColor: "#007bff",
    secondaryColor: "#6c757d",
  },
};

export const getTheme = (theme: Theme) => themes[theme];

4.在app.tsx 挂载


import { ThemeProvider } from "@/theme/ThemeContext";

const App = () => {
  return (
    <ThemeProvider>
      <div>App<div>
    </ThemeProvider>
  );
};

export default observer(App);

6.使用直接写样式方式一

// @live
import { useEffect } from "react";
import { css, cx } from "@emotion/css";
import { useTheme } from "@/theme/ThemeContext";
import { getTheme } from "@/theme/themeConfig";
import "./index.less";
const ThemeBox: any = () => {
  const { theme, toggleTheme } = useTheme();
  const currentTheme = getTheme(theme);

  const styles = css`
    background-color: ${currentTheme.color};
  `;
  return (
    <div className={cx("cockpit-contain", styles)} onClick={toggleTheme}>
    </div>
  );
};

export default ThemeBox;

6.使用类名方式二

// @live
import { useEffect } from "react";
import { css, cx } from "@emotion/css";
import { useTheme } from "@/theme/ThemeContext";
import { getTheme } from "@/theme/themeConfig";
import "./index.less";
const ThemeBox: any = () => {
  const { theme, toggleTheme } = useTheme();
  const currentTheme = getTheme(theme);

  const styles = css`
    .background {
      background-color: ${currentTheme.background};
    }
    .boder-color {
      border-color: ${currentTheme.borderColor};
    }
  `;
  return (
    <div className={cx("cockpit-contain", styles)} onClick={toggleTheme}>
        <div className={"background"}></div>
        <div className={"boder-color"}></div>
    </div>
  );
};

export default ThemeBox;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值