在旧版本的duxapp,支持主题功能,但是那时候的主体是静态配置的,并不支持动态切换,新版本,在旧的静态主题基础上扩展,实现了动态主题切换

旧版本静态主题

在之前的版本中已经支持主题功能,在用户配置用,使用模块的 theme 字段配置主题,像下面这样

// configs/config/index.js
option: {
// 基础模块
duxapp: {
theme: {
primaryColor: '#CDDE00',
secondaryColor: '#FDD000',
successColor: '#34a853',
warningColor: '#fbbc05',
dangerColor: '#ea4335',
pageColor: '#fafbf8'
}
}
}

配置了这些主题参数,会通过一个脚本转化为scss变量被加入到全局scss变量中,就像下面这样

$duxappPrimaryColor: #CDDE00;
$duxappSecondaryColor: #FDD000;
$duxappSuccessColor: #34a853;
$duxappDangerColor: #ea4335;
$duxappWarningColor: #fbbc05;
$duxappPageColor: #fafbf8;

然后你就能在任何scss文件中调用这些变量,例如 duxappStyle 的全局scss中调用这些变量,当然也不局限于这个文件,任何的scss都能调用这些变量

// src/duxappStyle/app.scss
.bg-primary {
background-color: $duxappPrimaryColor;
} .bg-secondary {
background-color: $duxappSecondaryColor;
} .bg-success {
background-color: $duxappSuccessColor;
}

然后在你的项目中就可以调用这些全局类名就能获得对应的样式

<View className='bg-primary' />

如果要编写 style 的时候获取这些主题参数,可以像下面这样

import { duxappTheme } from '@/duxapp'

<View style={{ backgroundColor: duxappTheme.primaryColor }} />
  • 关于如何定制自己模块的主题,查看这个文档

新版本的动态主题

为了最小的升级成本,系统未对之前的主题系统进行大改,而是在当前的主题系统模式上进行简单调整就能使用

之前所有的内容在新的主题系统中都是生效的,如果你要切换到动态主题,只需要在用户配置中,配置多套主题即可

  • 将当前的模块配置中的 theme 移动到 themes.light (每个模块的配置都需要同样的操作)
  • themes 里面新增一个主题配置 dark,表示夜间模式的主题

    :::info
  • 如果没有指定 themeConfig.default light将会作为默认主题,
  • 在你配置 dark 的主题的时候,如果和默认配置 light 相同的配置,你可以不配置,只需要与 light 不同的部分即可

    :::
  • 新增 themeConfig 配置项目,参考下面的示例,需要在里面配置主题列表 themes (必须配置) 其他三个选项为可选配配置,dark 用于指定页面模式主题,light 用于指定白天模式主题,default 指定默认主题
  • 只有当夜间模式和白天模式两个主题都存在的情况下系统才会跟随系统主题进行系统切换
  • 除了 light dark 你还可以配置更多的主题,通过 theme.setMode(主题) 切换
const config = {
option: {
// 基础模块
duxapp: {
themeConfig: {
themes: {
light: {
name: '明亮主题',
color: '#fff'
},
dark: {
name: '暗黑主题',
color: '#333'
}
},
// dark: 'dark',
// light: 'light',
// default: 'light'
},
themes: {
light: {
primaryColor: '#E70012',
secondaryColor: '#0092e8',
successColor: '#34a853',
warningColor: '#fbbc05',
dangerColor: '#ea4335',
pageColor: '#F7F9FC', textColor1: '#373D52',
textColor2: '#73778E',
textColor3: '#A1A6B6',
textColor4: '#FFF',
header: {
color: '#fff', // 仅支持rgb hex值,请勿使用纯单词 设置为数组将显示一个渐变按钮
textColor: '#000', // 文本颜色
showWechat: true, // 微信公众号是否显示header
showWap: true, // h5是否显示header
}
},
dark: {
pageColor: '#1E1E1E', whiteColor: '#181818',
blackColor: '#fff',
lineColor: '#1F1F1F', textColor1: '#FFF',
textColor2: '#A1A6B6',
textColor3: '#73778E',
textColor4: '#373D52',
header: {
color: '#121212',
textColor: '#fff'
},
loading: {
dark: '#fff',
blank: '#7a7a7a'
}
}
}
},
duxui: {
themes: {
light: {
button: {
radiusType: 'round'
}
},
dark: {
tabBar: {
nameColor: '#888',
nameHoverColor: '#fff'
}
}
}
}
}
} export default config

动态切换

默认情况下只需要你配置了 lightdark 两个主题,程序就能跟随系统自动切换

如果你需要手动切换,下面是一动态切换主题的示例代码,参考这个进行开发,theme 是基础模块导出的工具

:::info

  • 动态切换(包括自动切换)现在仅支持 小程序 H5端,其他平台还在开发中
  • 不支持的平台会按照配置的默认主题显示

    :::
import { Header, ScrollView, TopView, GroupList, theme, Button } from '@/duxuiExample'

export default function ThemeExample() {

  const mode = theme.useMode(true)

  const modes = theme.useModes()

  return <TopView>
<Header title='Theme' />
<ScrollView>
<GroupList>
<GroupList.Item title='主题切换功能' desc='主题切换当前仅支持小程序和H5端,其他端还在努力开发中'
className='gap-3'
>
{
modes.map(item => <Button
type='primary'
plain={item.mode !== mode}
key={item.name}
onClick={() => item.switch()}
size='l'
>{item.name}</Button>)
}
</GroupList.Item>
</GroupList>
</ScrollView>
</TopView>
}

如何实现的

动态主题在不同的平台使用了不同的实现方案,具体来说,小程序 H5端使用了css变量,RN端使用了插件动态修改组件代码实现动态切换

小程序 H5端

小程序 H5端 css 变量 的实现流程

  • duxapp-cli 先将用户配置的主题名称进行统计并存储
  • duxapp-cli 根据用户主题配置生成主题scss文件 src/duxapp/userTheme/index.scss,这个文件会自动被 TopView组件引用
  • 编写一个 theme-loader 将其插入到 webpack 的 loader 中,在处理 scss 之前,先解析动态主题,目的是将调用到scss主题变量的代码,替换为调用css变量
  • 主题系统通过一个改变类型动态切换css变量的流程

RN端

  • duxapp-cli 先将用户配置的主题名称进行统计并存储
  • duxapp-cli 根据用户主题配置生成主题js文件 src/duxapp/userTheme/index.rn.js
  • 编写一个 theme-loader 将其插入到 webpack 的 loader 中,在处理 scss 之前,先解析动态主题,目的是将调用到scss主题变量的代码,替换为调用css变量
  • 使用 patch-package 修改了 rn 端相关插件,主要改变的功能是,解析 theme-loader 生成的css变量,并替换成主题变量,并且将之前的 styleSheet 修改为函数的方式导出,函数接受一个主题名称,传入不同的主题名称,返回不同的 styleSheet
  • 修改插件,让插件在函数组件的头部,插入一个 hook ,这个 hook 会监听主题改变,并更新 styleSheet 并且在主题更新后,重新渲染组件

因为 React 组件的编写形式太过灵活多变,因此最后一步,在函数组件头部插入一个hook的操作,并不一定所有组件都能插入,局具体使用的显示参考这个说明

最后

duxapp的主题系统经历了从静态配置到动态切换的演进过程:

  • 兼容性:新版本完美兼容旧版的静态主题配置

  • 灵活性:支持多主题配置和动态切换

  • 跨平台:针对不同平台采用最优实现方案

  • 易用性:提供简洁的API和配置方式

开发者可以根据项目需求选择合适的主题方案,通过简单的配置即可实现强大的主题功能。未来版本将继续优化各平台的兼容性和性能表现。

主题开发文档

开发文档

GitHub

duxapp中主题系统是如何实现动态切换的的更多相关文章

  1. Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法

    一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...

  2. Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源方法

    一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...

  3. Pytest测试框架一键动态切换环境思路及方案

    前言 在上一篇文章<Pytest fixture及conftest详解>中,我们介绍了fixture的一些关键特性.用法.作用域.参数等,本篇文章将结合fixture及conftest实现 ...

  4. IOS中调用系统的电话、短信、邮件、浏览功能

    iOS开发系列--通讯录.蓝牙.内购.GameCenter.iCloud.Passbook系统服务开发汇总 2015-01-13 09:16 by KenshinCui, 26990 阅读, 35 评 ...

  5. 总结一下Android中主题(Theme)的正确玩法

    在AndroidManifest.xml文件中有<application android:theme="@style/AppTheme">,其中的@style/AppT ...

  6. Silverlight4中实现Theme的动态切换

    Silverlight一般用来开发一些企业的应用系统,如果用户一直面对同一种风格的页面,时间长了难免厌烦,所以一般都会提供好几种风格及Theme供用户选中,下面就来说一下如何在不重新登录系统的情况下, ...

  7. 在Linux中创建静态库.a和动态库.so

    转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...

  8. 【转载】总结一下Android中主题(Theme)的正确玩法

    http://www.cnblogs.com/zhouyou96/p/5323138.html 总结一下Android中主题(Theme)的正确玩法 在AndroidManifest.xml文件中有& ...

  9. linux中C的静态库和动态库分析

    从开始学C语言写第一个"hello world"历程到现在,我依然困惑于到底这个程序完整的执行流程是什么样的.不过,现在我正在尝试一点一点的揭开它的面纱.现在,我尝试分析linux ...

  10. QT皮肤系统的动态切换

    应用需求: 提供皮肤切换选项,在不重启应用程序的情况下实现皮肤的动态切换. 理论基础: 1) 图片资源是如何被利用的 这里先简要说明一下实现原理,皮肤的动态切换其关键在于图片资源的加载方式.QT中每个 ...

随机推荐

  1. ElementPlus插件的安装和使用

    ElementPlus插件安装和使用 npm install element-plus --save src/main.ts新增 // 关键节点:全局注册 Element Plus,包含样式 impo ...

  2. SmolVLM2轻量级视频多模态模型,应用效果测评(风景、事故、仿真、统计、文字、识物)

    SmolVLM2轻量级视频多模态模型,应用效果测评 目       录 1.     前言... 2 2.     应用部署... 2 3.     应用效果... 4 1.1          风景 ...

  3. Spring注解之@Async:Spring Boot实现异步调用

    前言 在日常开发过程中,会遇到一些需求是和主业务逻辑低耦合的,不要求和主业务逻辑同步进行,比如记录日志信息.发送消息通知电子邮件.生成PDF合同和导出报表等需求,而且,这些需求往往处理起来比较耗时.这 ...

  4. Kubernetes中Service学习笔记

    我们知道 Pod 的生命周期是有限的.可以用 ReplicaSet 和Deployment 来动态的创建和销毁 Pod,每个 Pod 都有自己的 IP 地址,但是如果 Pod 重建了的话那么他的 IP ...

  5. Django REST Framework框架介绍以及简单使用

    一. Django REST framework介绍 Django REST framework是基于Django实现的一个RESTful风格API框架,能够帮助我们快速开发RESTful风格的API ...

  6. Ceph对象存储集群常用操作

    一.常用操作 1.1 查看某个bucket详情 # 查看bucket列表 [root@oss001 ~]# radosgw-admin bucket list [ "awss3e68c588 ...

  7. PI发布rest,json接口

    PI接口的开发分成两个部分,第一个部分是ESB(Enterprise Services Builder)部分,这里注意做数据结构定义,接口导入,字段关系映射,定义接口等. 第二部分是IB(Integr ...

  8. 【深入理解Spring AOP】核心原理与代理机制详解

    深入理解Spring AOP:核心原理与代理机制详解 引言 在现代Java开发中,面向切面编程(AOP)已经成为解决横切关注点的主流方案.作为Spring框架的核心模块之一,Spring AOP通过代 ...

  9. 开源技术交流丨ChengYing部署Hadoop集群实战

    一.直播介绍 上期雅泽同学对ChengYing是什么.有什么样的功能特性,如何快速入门做了介绍,本期海洋同学将会为大家分享ChengYing部署Hadoop集群实战的相关内容,欢迎大家积极参与. 二. ...

  10. linux0.01代码阅读

    代码地址: https://cdn.kernel.org/pub/linux/kernel/Historic/linux-0.01.tar.gz 代码目录: main函数: 代码中的命名解释: CMO ...