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

相关推荐
学习使我快乐0123 分钟前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio199523 分钟前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
黄尚圈圈1 小时前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水2 小时前
简洁之道 - React Hook Form
前端
正小安4 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch6 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光6 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   6 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   6 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web6 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery