背景
希望网站可以实现 亮/暗 模式,并且每个模式都有自己的主题色,也就是网站有亮色主题,暗黑主题
搭建环境
现在官方是推荐使用 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/...