React动态主题+暗黑主题(umi3)

1,549 阅读2分钟

动态主题

动态主题,主要是在在系统中切换主题,实现页面主题色变化

暗黑主题,简单理解就是夜间模式

灰色主题,有颜色的地方一切置灰

色弱主题,通过设置css,达到页面颜色饱和度的变化

动态主题:动态主题

umi中使用的基于 CSS Variable实现方式,但是注意不支持ie11

  1. 首先在入口config配置文件中, theme的主题色不可以写死

    theme: {
        //为了让less是值是可变的
        'root-entry-name': 'variable',
    }
    
  2. 在全局global.less 样式的入口文件中手动导入antd的样式

    @import (reference) '~antd/es/style/themes/index';
    
  3. 拿到antd中的方法,ConfigProvider你就可以随心所欲的配置样式了

    import { ConfigProvider } from 'antd';
    
    ConfigProvider.config({
      theme: {
        primaryColor: '#25b864',
      },
    });
    

111.PNG

222.PNG


暗黑主题:darkreader

乖乖听antdpro的话,也是基于darkreader实现的

  1. 第一步按照插件

    npm install darkreader
    
  2. 然后主要就是两个API,

    import {
      enable as enableDarkMode,
      disable as disableDarkMode,
      setFetchMethod as setFetch,
    } from '@umijs/ssr-darkreader'; 
    
    //开启 暗黑模式
    enableDarkMode({
              brightness: 100,
              contrast: 90,
              sepia: 10,
    });
    
    //关闭 暗黑模式
    disableDarkMode();
    
  3. ok就是这么so easy

333.PNG


灰色模式

这个也是很简单的,需要使用css的滤镜功能

  1. 获取到页面元素

     const html = document.documentElement;
    
  2. 给页面元素添加css属性

     html.setAttribute('style', 'filter: grayscale(1)');
    
  3. 大功告成

444.PNG


色弱模式

与灰色模式类似,只不过数据不同

  1. 获取到页面元素

     const html = document.documentElement;
    
  2. 给页面元素添加css属性

     html.setAttribute('style', 'filter: invert(80%)');
    

555.PNG


基于上述实现的,主题切换组件

动态主题色:
  1. 先在redux中存入默认颜色,在颜色获取组件用获取redux中的数据,
  2. 使用useEffect进行监听,并触发ConfigProvider设置主题色
  3. 在组件中渲染多个主题色供用户选择,用户点击后更改redux暂存的主题色
  4. 如果想持久化可以考虑存服务器中,或本地持久化存储
暗黑模式|灰色模式|色弱模式:
  1. 封装一个出来主题的钩子

    export const useTheme = (themeType: string) => {
      //获取整个页面元素
      const html = document.documentElement;
      switch (themeType) {
        case 'greyTheme':
          html.setAttribute('style', 'filter: grayscale(1)');
          break;
        case 'AchromaticTheme':
          html.setAttribute('style', 'filter: invert(80%)');
          break;
        case 'darkTheme':
          if (window.MutationObserver && window.fetch) {
            setFetch(window.fetch);
            enableDarkMode({
              brightness: 100,
              contrast: 90,
              sepia: 10,
            });
          }
          break;
        default:
          disableDarkMode();
          html.setAttribute('style', '');
          break;
      }
    };
    
    
  2. 每次点击操作传入对应的主题类型,实现主题的变化

666.PNG