主题管理
DHdesign 的主题分三层管理:
@szhn/theme-tokens保存公司统一的基础值,比如品牌色、功能色、字号、圆角和间距。@szhn/dh-design-mobile把这些基础值转换成移动端组件和 Vant 能识别的变量。@szhn/dh-design-pc把这些基础值转换成 PC 组件和 Element Plus 能识别的变量。
因此,移动端看到 --dh-color-primary,PC 端看到 --dh-color-primary,并不代表有两套品牌规则。它们只是分别适配 Vant 和 Element Plus 的入口。真正的默认值应该来自 @szhn/theme-tokens。
修改主题色
业务系统不要直接改 --van-* 或 --el-* 变量。推荐在应用入口处设置一次 DHdesign 主题。
import { applyDhDesignTheme } from '@szhn/dh-design-mobile'
applyDhDesignTheme({
colorPrimary: '#075AED',
})import { applyDhDesignPcTheme } from '@szhn/dh-design-pc'
applyDhDesignPcTheme({
colorPrimary: '#075AED',
})只传 colorPrimary 时,DHdesign 会自动推导浅色、弱色、禁用色、背景色及相关透明色。传入默认主色不会改变官方色板;功能色也使用统一的派生规则。业务系统只有在确实需要更细的品牌控制时,才需要继续覆盖 colorPrimaryLight、colorPrimarySoft、colorPrimaryDisabled、colorPrimaryBg。
不同服务使用不同主题
把每个服务的主题收敛成一个配置对象,然后在应用入口按服务选择。
const serviceThemes = {
default: {
colorPrimary: '#075AED',
},
medical: {
colorPrimary: '#0F7A5A',
},
emergency: {
colorPrimary: '#B81B1B',
},
}移动端项目使用 applyDhDesignTheme(serviceThemes.medical),PC 项目使用 applyDhDesignPcTheme(serviceThemes.medical)。业务页面不需要知道 Vant 或 Element Plus 的变量名。
Vue2 老项目默认不需要手动配置主题。只要引入对应兼容包的 style.css,组件包会带上 DHdesign 默认字体、颜色、间距和圆角。
需要换品牌色或做项目专属主题时,再使用对应兼容包的主题方法:
import { applyDhDesignMobileVue2Theme } from '@szhn/dh-design-mobile-vue2/theme'
import { applyDhDesignPcVue2Theme } from '@szhn/dh-design-pc-vue2/theme'主题值仍然来自同一套 DHdesign 设计变量。区别只是 Vue2 包会适配到 Vant 2 或 Element UI。
容器级主题与同页混用
同页使用 PC、Mobile 或多个主题时,使用各包的 styles/scoped.css,不要再同时引入全局 style.css。全量插件安装时传入 { themeTarget: false },避免向根节点写主题;也可以只按需引入组件。
<script setup lang="ts">
import { PcThemeProvider } from '@szhn/dh-design-pc/theme'
import ElSelect from '@szhn/dh-design-pc/components/select'
import '@szhn/dh-design-pc/styles/scoped.css'
</script>
<template>
<PcThemeProvider :theme="{ colorPrimary: '#6B46D1' }" v-slot="{ teleportTarget }">
<ElSelect :append-to="teleportTarget" />
</PcThemeProvider>
</template>MobileThemeProvider 从 @szhn/dh-design-mobile/theme 引入,Vant 弹层使用 :teleport="teleportTarget"。Provider 会在 body 下创建同主题的浮层容器,并随主题更新、随组件卸载移除。弹层必须显式指定该目标;直接 Teleport 到 body 的弹层不会继承页面容器主题。消息等函数式服务也需要指定相应的 appendTo 或 teleport。
只想为已有容器设置主题时,可以传模板引用:
const container = ref<HTMLElement | null>(null)
useDhDesignPcTheme({ colorPrimary: '#6B46D1' }, container)引用未挂载时不会误写全局;引用变化或作用域销毁时会恢复此前的内联变量。不传第二个参数保留原来的全局行为。插件也接受 { theme, themeTarget: element }。
默认 CSS 的维护
默认 theme.css 和 theme-scoped.css 由实际主题解析函数生成,不再手工维护一份语义色值。修改 tokens 或平台映射后运行 pnpm build:theme-css;组件包构建也会自动生成。
常用设计变量
| 类型 | 变量示例 | 说明 |
|---|---|---|
| 品牌色 | colorPrimary、colorPrimaryLight、colorPrimaryBg | 主按钮、链接、选中态、浅色背景 |
| 功能色 | colorSuccess、colorWarning、colorDanger | 成功、警告、危险状态 |
| 文字色 | colorTextPrimary、colorTextSecondary、colorTextPlaceholder、colorTextDisabled | 正文、辅助文字、占位文字、禁用文字 |
| 字体 | fontFamily、fontSizeBase、fontSizeMd、lineHeightBase | 全局字体、常用字号和行高 |
| 间距 | space8、space12、space16、space24、space32 | 单元格、表单、弹层、卡片等常用留白 |
| 圆角 | radius4、radiusMedium、radius12、radius16、radiusPill | 标签、按钮、弹窗、弹层、胶囊 |
| 组件尺寸 | buttonHeight、buttonHeightSmall、fieldHeight、fieldPadding | 按钮和输入框基础尺寸 |
Vue2 兼容包会优先把这些变量应用到常用组件。Vant 2 和 Element UI 的旧样式不是完整运行时变量体系,所以 Vue2 包除了声明变量,还内置了一层组件样式覆盖。
什么时候才直接改底层变量
只有两种情况建议直接改底层变量:
- 某个 Vant 或 Element Plus 组件有 DHdesign 暂时没有覆盖到的细节变量。
- 单个页面需要临时做很小范围的特殊样式。
这类改动应该写在页面局部,不要替代全局主题配置。
