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

相关推荐
折果42 分钟前
如何在vue项目中封装自己的全局message组件?一步教会你!
前端·面试
不死鸟.亚历山大.狼崽子1 小时前
Syntax Error: Error: PostCSS received undefined instead of CSS string
前端·css·postcss
汪子熙1 小时前
Vite 极速时代的构建范式
前端·javascript
跟橙姐学代码1 小时前
一文读懂 Python 的 JSON 模块:从零到高手的进阶之路
前端·python
前端小巷子1 小时前
Vue3的渲染秘密:从同步批处理到异步微任务
前端·vue.js·面试
nightunderblackcat2 小时前
新手向:用FastAPI快速构建高性能Web服务
前端·fastapi
小码编匠2 小时前
物联网数据大屏开发效率翻倍:Vue + DataV + ECharts 的标准化模板库
前端·vue.js·echarts
欧阳天风3 小时前
分段渲染加载页面
前端·fcp
艾小码3 小时前
TypeScript在前端的实践:类型系统助力大型应用开发
前端·typescript
今禾3 小时前
前端工程化的范式革命:从 Webpack 的“全量打包”到 Vite 的“按需编译”
前端·webpack·vite