关于 umi3 主题配置之旅以及使用方法

需求背景

在进行项目开发到一半或者已经完成开发时,客户方想要加入在线预设主题切换的效果

制定方案

方案一:使用 less 全局变量

方案二:使用 antd 提供的变量

通过引入使用 antd 提供的变量样式文件,实现对antd主题化配置,从而达到目标需求(实际也是根据less变量来配置,只不过antd已经帮你实现了)参考下面链接

https://zhuanlan.zhihu.com/p/400808568

方案三:使用 var css 实现

需浏览器支持,编写复杂

方案四:使用样式覆盖

预设多个主题文件,通过切换样式文件进行覆盖达到目的

方案五:使用他人编写插件

参考以下链接

  • umi插件:

https://zhuanlan.zhihu.com/p/347725244

  • webpack插件:

https://zhuanlan.zhihu.com/p/375347921

辛路历程(踩坑)

  • 最esay的就是引用别人成熟的方案,不过需要对项目进行适配;

  • 首先选用的是方案五中Webpack插件,文档中配置较多,对人员可能有一定的要求(后续会对该插件进行底层实现调研);

  • 其次是Umi插件(没有运行起来😑),由于是非官方插件,安全性有待商榷;

  • 方案一,方案三和方案四有很高的局限性;

  • 方案二可以是备选解,但依然有着局限性,完全依赖于组件库;

正在我困扰时我找到了以下文章:

https://juejin.cn/post/7034099025917771790

最终实现方案

目录结构

文件夹

描述

备注

styles

主文件夹

详见 readme

common

用于存放样式块

统一有 index.less 抛出【详见 readme】

constant

用于存放样式常量

所有样式中的颜色,字体大小等都应由 constant 抛出

cover

用于覆盖组件库样式

\---

themes

用于配置主题与抛出主题样式

详见 readme

使用css变量,和less变量进行组合实现主题切换

// --- var.theme.less ---
    @xxx_primary_color: var(--scm_primary_color);
    @xxx_success_color: var(--scm_success_color);
    @xxx_warning_color: var(--scm_warning_color);
    @xxx_error_color: var(--scm_error_color);

设置全局变量

使用style-resources-loader

// --- .umirc.js ---
    // 在umi 配置的 chainWebpack 中引入loader
    // 添加全局less变量
    config.module
      .rule('less-global')
      .test(/\\\\.less$/)
      .use('style-resources')
      .loader('style-resources-loader')
      .options({
      patterns: [path.resolve(__dirname, 'src/themes/var.theme.less')],
    });

参考:

https://juejin.cn/post/7051476074693132296

先不指定变量默认值,首次设置默认主题!

在初始化数据中请求用户设置主题,若为 null 则设置默认主题

支持 CssModule

实现效果

// TODO

配置(如何使用)

规则(以xxx(项目缩写)开头,以\\\\_分割)

    @xxx_primary_color; // 全局主色
    @xxx_link_color; // 链接色
    @xxx_success_color; // 成功色
    @xxx_warning_color; // 警告色
    @xxx_error_color; // 错误色
    @xxx_font_size_base; // 主字号
    @xxx_heading_color; // 标题色
    @xxx_text_color; // 主文本色
    @xxx_text_color_secondary; // 次文本色
    @xxx_disabled_color; // 失效色
    @xxx_border_radius_base; // 组件/浮层圆角
    @xxx_border_color_base; // 边框色
    @xxx_box_shadow_base; // 浮层阴影
    // 等等

由于开启全局变量引入,不需要在各自文件中引入var.theme.less文件

适用的项目

::: less或者sass作为主要样式开发的项目,需要浏览器支持css变量 :::

后续改进

  • [ ] 兼容性问题

  • [ ] 插件化

  • [ ] 可扩展

  • [x] 常量收敛

详见 constant 文件夹

  • [x] js 中使用

详见 styles/index.js

创建上下文使用 withStyle hoc 在包裹的组件内消费,随主题的改变更新上下文重新渲染 withStyle 包裹的组件

相关链接

https://juejin.cn/post/7034099025917771790

https://zhuanlan.zhihu.com/p/347725244

https://zhuanlan.zhihu.com/p/375347921

https://zhuanlan.zhihu.com/p/400808568

https://juejin.cn/post/7051476074693132296

相关仓库

https://github.com/GitOfZGT/some-loader-utils

https://github.com/alitajs/umi-theme-generator

评论