umi3 +ant4 ,动态主题实现(包含源码)

背景

希望网站可以实现 亮/暗 模式,并且每个模式都有自己的主题色,也就是网站有亮色主题,暗黑主题

搭建环境

现在官方是推荐使用 umi 4,所以想要下载 umi 3,通过脚手架下载是下载不了了,需要如下步骤: ❌:yarn create umi或者其他脚手架的方式,目前我测试下载的都是最新的 umi4 版本 ✅: git clone -b umi@3 git@github.com:ant-design/ant-design-pro.git my-project 安装好,先 yarn install安装依赖,然后yarn start:dev启动项目

注意:我的电脑在 node 版本 16.18.0安装依赖失败,解决办法是升级 node 版本(我是升级到 18.16.0),但是高 node 版本,又启动不了项目,我会继续回到16.18.0来运行项目

开发主题切换组件

1)src 下创建 constants 文件夹,下面新建 theme.ts 文件

css 复制代码
export const Theme_Token = {
  light: {
    primaryColor: '#25b864',
  },
  dark: {
    primaryColor: '#b825b8',
  },
};
​

src 下创建 hooks 文件夹,下面新增 useThemeChange.ts 文件

typescript 复制代码
import { useState } from 'react';
interface TypeTheme {
  theme: 'light' | 'dark' | 'auto';
  setTheme: (theme: 'light' | 'dark' | 'auto') => void;
}
const useThemeChange = () => {
  const [theme, setTheme] = useState<TypeTheme['theme']>('light');
  const changeTheme = (t: TypeTheme['theme']) => {
    setTheme(t);
  };
  return {
    theme: theme,
    changeTheme,
  };
};
​
export default useThemeChange;
​

src 下 components 文件夹,下面新增 AntdThemeSwitch.ts 文件

typescript 复制代码
import React from 'react';
import Light from '@/assets/light.svg';
import Dark from '@/assets/dark.svg';
import ThemeAuto from '@/assets/theme-auto.svg';
import { Menu, Avatar, Dropdown, ConfigProvider } from 'antd';
import { enable as enableDarkMode, disable as disableDarkMode } from '@umijs/ssr-darkreader';
​
import './index.less';
import useThemeChange from '@/hooks/useThemeChange';
import { Theme_Token } from '@/constants/theme';
const themeMap = {
  auto: ThemeAuto,
  light: Light,
  dark: Dark,
};
​
const AntdThemeSwitch = () => {
  // @ts-ignore
  console.log(window.umi_plugin_ant_themeVar, 'window.umi_plugin_ant_themeVar');
​
  const { theme, changeTheme } = useThemeChange();
  const onMenuClick = async (event: { key: React.Key; keyPath: React.Key[] }) => {
    const { key } = event;
    changeTheme(key as 'light' | 'dark' | 'auto');
    if (key === 'dark') {
      //开启 暗黑模式
      enableDarkMode({
        brightness: 100,
        contrast: 90,
        sepia: 10,
      });
    } else {
      //关闭 暗黑模式
      disableDarkMode();
    }
    // 修改 antd 主题
    ConfigProvider.config({
      theme: Theme_Token[key],
    });
    // 修改 localStorage
    localStorage.setItem('theme', key as string);
  };
​
  /**
   * 下拉菜单
   */
  const menuHeaderDropdown = (
    <Menu className="menu" onClick={onMenuClick}>
      {/* <Menu.Item className="minWidth" key="auto">
        <Avatar size={20} src={themeMap.auto} />
        跟随系统
      </Menu.Item> */}
      <Menu.Item className="minWidth" key="light">
        <Avatar size={20} src={themeMap.light} />
        亮色
      </Menu.Item>
      <Menu.Item className="minWidth" key="dark">
        <Avatar size={20} src={themeMap.dark} />
        暗色
      </Menu.Item>
    </Menu>
  );
  return (
    <div className="antd-theme-switch">
      <Dropdown overlayClassName="theme-container" overlay={menuHeaderDropdown}>
        <div className="">
          <Avatar size={20} src={themeMap[theme]} />
        </div>
      </Dropdown>
    </div>
  );
};
​
export default AntdThemeSwitch;
​

demo 地址 :github.com/chaseFunny/...

相关推荐
JIngJaneIL5 分钟前
基于java + vue连锁门店管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
Mintopia5 分钟前
🧠 从零开始:纯手写一个支持流式 JSON 解析的 React Renderer
前端·数据结构·react.js
消失的旧时光-194317 分钟前
Flutter 工程中 mixin 的正确打开方式:5 种高质量设计范式 + mixin vs 继承 vs 组合 + 为什么它比 BasePage 更优雅
前端·flutter·架构
乐吾乐科技21 分钟前
乐吾乐3D可视化2025重大更新与2026升级计划
前端·3d·信息可视化·编辑器·数据可视化
C_心欲无痕21 分钟前
html - 使用视频做天气卡片背景
前端·html·音视频
毕设十刻39 分钟前
基于Vue的养老服务平台85123(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
青衫折扇41 分钟前
执行 npm 安装命令时,包被装到了 C 盘用户目录下,而非项目根目录
前端·npm·node.js
XiaoYu20021 小时前
第2章 Nest.js入门
前端·ai编程·nestjs
没事多睡觉6661 小时前
零基础React + TypeScript 教程
前端·react.js·typescript
liliangcsdn1 小时前
MySQL存储字节类数据的方案示例
java·前端·数据库