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/...

相关推荐
码上成长3 分钟前
包管理提速:pnpm + Workspace + Changesets 搭建版本体系
前端·前端框架
Bigger6 分钟前
Tauri(十九)——实现 macOS 划词监控的完整实践
前端·rust·app
ganshenml1 小时前
【Web】证书(SSL/TLS)与域名之间的关系:完整、通俗、可落地的讲解
前端·网络协议·ssl
这是个栗子2 小时前
npm报错 : 无法加载文件 npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
HIT_Weston2 小时前
44、【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 分析(一)
前端·ubuntu·gitlab
华仔啊3 小时前
Vue3 如何实现图片懒加载?其实一个 Intersection Observer 就搞定了
前端·vue.js
JamesGosling6663 小时前
深入理解内容安全策略(CSP):原理、作用与实践指南
前端·浏览器
不要想太多3 小时前
前端进阶系列之《浏览器渲染原理》
前端
g***96903 小时前
Node.js npm 安装过程中 EBUSY 错误的分析与解决方案
前端·npm·node.js
七喜小伙儿3 小时前
第2节:趣谈FreeRTOS--打工人的日常
前端