主题配置
# 主题配置
# 概述
通过工具函数可以全局设置主题模式,支持两种主题:white(亮色主题)和 dark(暗色主题)。
主题系统采用统一的 CSS 变量架构,主题切换时会同时设置两套变量:
| 变量前缀 | 用途 |
|---|---|
--el-* | 覆盖 Element UI 组件样式 |
--xt-* | xt-element-ui 自定义组件样式 |
两套变量保持同步,确保 Element UI 原生组件和 xt 组件在主题切换时表现一致。
# 架构说明
┌─────────────────────────────────────────────┐
│ utils/theme.js │
│ ┌─────────────────────────────────────┐ │
│ │ applyThemeVars(element, config) │ │ ← 唯一事实源
│ │ - LIGHT_THEME_VARS / DARK_THEME_VARS│ │
│ │ - BRAND_COLORS │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
▲ ▲
│ 调用 │ 调用
┌─────────┴──────┐ ┌───────┴────────────┐
│ utils/index.js │ │ theme/iframe- │
│ setTheme() │ │ injector.js │
│ setPrimaryColor()│ │ iframe 主题同步 │
└─────────────────┘ └────────────────────┘
# 方法说明
# setTheme(theme)
设置全局主题,同时更新 --el-* 和 --xt-* 两套 CSS 变量。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
theme | String | 是 | 主题类型:white、dark |
<template>
<div>
<XtButton @click="setWhiteTheme">亮色主题</XtButton>
<XtButton @click="setDarkTheme">暗色主题</XtButton>
</div>
</template>
<script>
import { setTheme } from 'xt-element-ui'
export default {
methods: {
setWhiteTheme() {
setTheme('white')
},
setDarkTheme() {
setTheme('dark')
}
}
}
</script>
内部行为:
- 调用
applyThemeVars()设置--el-*主题变量(主色、背景、文字、边框等) - 设置
--xt-*组件主色变量 - 在
<html>上设置data-theme属性 - 同步更新 ECharts 图表主题
# getTheme()
获取当前主题配置。
<template>
<div>
<XtText>当前主题:{{ currentTheme }}</XtText>
</div>
</template>
<script>
import { getTheme } from 'xt-element-ui'
export default {
computed: {
currentTheme() {
return getTheme()
}
}
}
</script>
# setPrimaryColor(color)
设置全局主色调,同时更新 --el-color-primary* 和 --xt-color-primary* 变量。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
color | String | 是 | 十六进制颜色值,如 #1890ff |
<template>
<div>
<XtButton @click="changePrimary('#ff5722')">橙色主题</XtButton>
<XtButton @click="changePrimary('#4caf50')">绿色主题</XtButton>
</div>
</template>
<script>
import { setPrimaryColor } from 'xt-element-ui'
export default {
methods: {
changePrimary(color) {
setPrimaryColor(color)
}
}
}
</script>
自动衍生变量:设置主色后会自动生成以下变量:
| 变量 | 说明 |
|---|---|
--el-color-primary | 主色 |
--el-color-primary-light-3 | 主色 +30% 亮度 |
--el-color-primary-light-5 | 主色 +50% 亮度 |
--el-color-primary-light-7 | 主色 +70% 亮度 |
--el-color-primary-light-8 | 主色 +80% 亮度 |
--el-color-primary-light-9 | 主色 +90% 亮度 |
--el-color-primary-dark-2 | 主色 -20% 亮度 |
--el-color-primary-rgb | 主色 RGB 值 |
# 主题对照表
| 主题 | 说明 |
|---|---|
white | 亮色主题,适合日间使用(默认值) |
dark | 暗色主题,适合夜间使用 |
# 使用示例
# 在组件安装时配置
import XtElementUI from 'xt-element-ui'
Vue.use(XtElementUI, {
theme: 'dark' // 全局设置暗色主题
})
# 动态切换主题
<template>
<div>
<XtFlexBox content="center" style="gap: 16px; margin-bottom: 16px;">
<XtButton
v-for="theme in themes"
:key="theme"
:type="currentTheme === theme ? 'primary' : ''"
@click="changeTheme(theme)"
>
{{ themeLabels[theme] }}
</XtButton>
</XtFlexBox>
<XtCard>
<XtCardItem title="当前主题">
<XtText type="primary" bold>{{ themeLabels[currentTheme] }}</XtText>
</XtCardItem>
<XtCardItem title="主题状态">
<XtText :type="currentTheme === 'dark' ? 'warning' : 'success'">
{{ currentTheme === 'dark' ? '暗色模式已开启' : '亮色模式已开启' }}
</XtText>
</XtCardItem>
</XtCard>
</div>
</template>
<script>
import { setTheme, getTheme } from 'xt-element-ui'
export default {
data() {
return {
themes: ['white', 'dark'],
themeLabels: {
white: '亮色',
dark: '暗色'
}
}
},
computed: {
currentTheme() {
return getTheme()
}
},
methods: {
changeTheme(theme) {
setTheme(theme)
}
}
}
</script>
# 监听主题变化
<template>
<div>
<XtText>主题变化次数:{{ changeCount }}</XtText>
</div>
</template>
<script>
import { onConfigChange } from 'xt-element-ui'
export default {
data() {
return {
changeCount: 0,
unsubscribe: null
}
},
mounted() {
// 监听主题变化
this.unsubscribe = onConfigChange((key, value) => {
if (key === 'theme') {
this.changeCount++
console.log('主题已切换为:', value)
}
})
},
beforeDestroy() {
// 取消监听
if (this.unsubscribe) {
this.unsubscribe()
}
}
}
</script>
# 微前端架构(iframe 场景)
主系统切换主题后,子系统 iframe 中的 Element UI 组件会自动同步换色。详细用法参见 iframe 主题注入。
// 主系统
import { setTheme } from 'xt-element-ui'
import { createThemeInjector } from 'xt-element-ui'
// 1. 创建注入器
const injector = createThemeInjector({ theme: 'white' })
// 2. 注入现有 iframe
injector.injectAll('iframe')
// 3. 切换主题(自动同步到所有 iframe)
setTheme('dark')
# 注意事项
- 主题切换会影响所有使用组件库样式的元素
- 设置后会在
html标签上添加/移除data-theme="dark"属性 setTheme和setPrimaryColor会同时设置--el-*和--xt-*两套变量- 建议在应用初始化时设置主题,可以结合用户偏好存储(如 localStorage)
- 微前端架构下,主系统通过
createThemeInjector可实现 iframe 自动同步