业务组件接入指南¶
📄 创建: 未记录
本文档说明如何在业务组件中正确消费主题模块提供的颜色变量。
核心原则¶
业务组件只消费颜色变量,不直接操作主题状态。
主题模块提供了完整的 CSS 变量系统,业务组件只需通过 var(--bams-*) 的方式引用这些变量即可。
全局颜色变量列表¶
主品牌色及其交互态¶
--bams-primary /* 主品牌色 */
--bams-primary-hover /* 主品牌色(悬停态) */
--bams-primary-active /* 主品牌色(激活态) */
--bams-primary-border /* 主品牌色(边框态) */
--bams-primary-text /* 主品牌色(文本态) */
--bams-primary-soft /* 主品牌色(弱化态) */
--bams-primary-bg /* 主品牌色(背景态) */
--bams-primary-bg-hover /* 主品牌色(背景悬停态) */
--bams-primary-outline /* 主品牌色(轮廓态) */
链接与信息态¶
--bams-link-color /* 链接色 */
--bams-link-hover /* 链接色(悬停态) */
--bams-link-active /* 链接色(激活态) */
--bams-info-color /* 信息提示色 */
--bams-info-text /* 信息提示色(文本态) */
--bams-info-border /* 信息提示色(边框态) */
--bams-info-bg /* 信息提示色(背景态) */
--bams-info-soft /* 信息提示色(弱化态) */
语义状态色¶
/* 成功 */
--bams-success-color /* 成功态颜色 */
--bams-success-text /* 成功态文本色 */
--bams-success-border /* 成功态边框色 */
--bams-success-bg /* 成功态背景色 */
--bams-success-soft /* 成功态弱化色 */
/* 警告 */
--bams-warning-color /* 警告态颜色 */
--bams-warning-text /* 警告态文本色 */
--bams-warning-border /* 警告态边框色 */
--bams-warning-bg /* 警告态背景色 */
--bams-warning-soft /* 警告态弱化色 */
/* 错误 */
--bams-error-color /* 错误态颜色 */
--bams-error-text /* 错误态文本色 */
--bams-error-border /* 错误态边框色 */
--bams-error-bg /* 错误态背景色 */
--bams-error-soft /* 错误态弱化色 */
页面与容器背景层级¶
--bams-page-bg /* 页面背景色 */
--bams-layout-bg /* 布局背景色 */
--bams-surface-bg /* 表面背景色 */
--bams-surface-bg-elevated /* 表面背景色(抬升态) */
--bams-surface-bg-muted /* 表面背景色(弱化态) */
--bams-content-bg /* 内容区背景色 */
--bams-toolbar-bg /* 工具栏背景色 */
--bams-sider-bg /* 侧边栏背景色 */
--bams-menu-bg /* 菜单背景色 */
菜单态¶
--bams-menu-text /* 菜单文本色 */
--bams-menu-selected-bg /* 菜单选中态背景色 */
--bams-menu-selected-text /* 菜单选中态文本色 */
--bams-menu-hover-bg /* 菜单悬停态背景色 */
文本层级¶
--bams-text-color /* 主文本色 */
--bams-text-secondary /* 次要文本色 */
--bams-text-tertiary /* 三级文本色 */
--bams-text-quaternary /* 四级文本色 */
--bams-text-disabled /* 禁用态文本色 */
--bams-text-placeholder /* 占位符文本色 */
--bams-text-inverse /* 反白文本色 */
边框层级¶
--bams-border-color /* 主边框色 */
--bams-border-secondary /* 次要边框色 */
--bams-border-strong /* 强边框色 */
--bams-divider-color /* 分割线色 */
头部与图标¶
--bams-header-bg /* 头部背景色 */
--bams-header-text /* 头部文本色 */
--bams-icon-color /* 图标色 */
--bams-icon-secondary /* 次要图标色 */
通用交互态¶
--bams-hover-bg /* 悬停态背景色 */
--bams-active-bg /* 激活态背景色 */
--bams-selected-bg /* 选中态背景色 */
--bams-disabled-bg /* 禁用态背景色 */
--bams-disabled-border /* 禁用态边框色 */
滚动条与阴影¶
--bams-scrollbar-thumb /* 滚动条滑块色 */
--bams-scrollbar-track /* 滚动条轨道色 */
--bams-shadow-header /* 头部阴影 */
--bams-shadow-card /* 卡片阴影 */
--bams-shadow-overlay /* 浮层阴影 */
遮罩与焦点态¶
浮层与弹出层¶
--bams-overlay-bg /* 浮层背景色 */
--bams-popover-bg /* 气泡卡片背景色 */
--bams-dropdown-bg /* 下拉菜单背景色 */
--bams-tooltip-bg /* 工具提示背景色 */
--bams-tooltip-text /* 工具提示文本色 */
表单与输入控件¶
--bams-input-bg /* 输入框背景色 */
--bams-input-bg-hover /* 输入框悬停态背景色 */
--bams-input-bg-disabled /* 输入框禁用态背景色 */
--bams-input-text /* 输入框文本色 */
--bams-input-placeholder /* 输入框占位符文本色 */
--bams-input-border /* 输入框边框色 */
--bams-input-border-hover /* 输入框悬停态边框色 */
--bams-input-border-focus /* 输入框聚焦态边框色 */
--bams-input-border-error /* 输入框错误态边框色 */
--bams-input-border-warning /* 输入框警告态边框色 */
--bams-input-shadow-focus /* 输入框聚焦态阴影 */
按钮¶
--bams-button-default-bg /* 默认按钮背景色 */
--bams-button-default-text /* 默认按钮文本色 */
--bams-button-default-border /* 默认按钮边框色 */
--bams-button-default-hover-bg /* 默认按钮悬停态背景色 */
--bams-button-primary-bg /* 主要按钮背景色 */
--bams-button-primary-text /* 主要按钮文本色 */
--bams-button-primary-hover-bg /* 主要按钮悬停态背景色 */
--bams-button-primary-active-bg /* 主要按钮激活态背景色 */
表格与列表¶
--bams-table-bg /* 表格背景色 */
--bams-table-header-bg /* 表格表头背景色 */
--bams-table-header-text /* 表格表头文本色 */
--bams-table-border /* 表格边框色 */
--bams-table-row-hover-bg /* 表格行悬停态背景色 */
--bams-table-row-selected-bg /* 表格行选中态背景色 */
--bams-table-row-striped-bg /* 表格斑马纹背景色 */
标签与徽标¶
--bams-tag-default-bg /* 默认标签背景色 */
--bams-tag-default-text /* 默认标签文本色 */
--bams-tag-default-border /* 默认标签边框色 */
在业务组件中使用全局变量¶
基本用法¶
在组件的 <style> 标签中直接使用 var(--bams-*) 引用变量:
<template>
<div class="business-card">
<div class="card-title">标题</div>
<div class="card-content">内容</div>
</div>
</template>
<style scoped lang="less">
.business-card {
background: var(--bams-surface-bg);
border: 1px solid var(--bams-border-color);
border-radius: 8px;
padding: 16px;
box-shadow: var(--bams-shadow-card);
.card-title {
color: var(--bams-text-color);
font-size: 16px;
font-weight: 500;
margin-bottom: 8px;
}
.card-content {
color: var(--bams-text-secondary);
font-size: 14px;
}
}
</style>
按钮样式示例¶
<style scoped lang="less">
.business-button {
background: var(--bams-button-primary-bg);
color: var(--bams-button-primary-text);
border: none;
border-radius: 6px;
padding: 8px 16px;
cursor: pointer;
transition: background 0.2s;
&:hover {
background: var(--bams-primary-hover);
}
&:active {
background: var(--bams-primary-active);
}
}
</style>
局部主题颜色变量的应用¶
需求背景¶
在实际业务开发中,有些组件需要相对独立的主题表现,不能完全受全局主题控制,典型场景包括:
- 第三方组件集成:需要为外部引入的组件适配项目主题,但又不想影响全局样式
- 特殊业务区域:如仪表盘、营销页面等需要独立配色以突出视觉效果
- 组件定制化:某些业务组件有特定的设计规范,需要独立的颜色体系
- 暗色模式适配:组件自身需要独立的暗色模式处理逻辑
此时可以使用局部主题方案,在不影响全局主题的前提下,为特定组件或区域提供独立的主题变量。
当业务组件需要独立的主题变量(不受全局主题影响)时,有以下几种方法:
局部主题定义规范¶
使用局部主题时必须遵循此规范。
使用局部主题时,必须将配置抽取到单独的文件中。
必须的文件结构:
src/
├── theme/ # 必须放在此目录
│ ├── xxxTheme.js # 必须使用此命名规范
│ └── yyyTheme.js
└── business/
└── components/
└── XxxComponent.vue # 导入主题配置
配置文件示例:
// src/theme/xxxTheme.js
export const THEME_MODE_VARS = {
light: {
"--component-bg": "#ffffff",
"--component-text": "#1e293b",
colorScheme: "light",
},
dark: {
"--component-bg": "#1e293b",
"--component-text": "#f1f5f9",
colorScheme: "dark",
},
};
export const THEME_PRESET_VARS = {
"material.blue": {
"--component-primary": "#0d6cbd",
},
};
组件中使用:
<script setup>
import { LocalThemeContainer } from "@bams-app/theme";
import { THEME_MODE_VARS, THEME_PRESET_VARS } from "../../theme/xxxTheme";
</script>
方法一:使用 ComponentContainer 或 PageWorkContainer 组件(最推荐)¶
对于业务组件的根容器,推荐使用 ComponentContainer 或 PageWorkContainer 组件,它们已经内置了主题变量处理功能。
Props 定义¶
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| containerStyle | 容器自定义样式 | Object | {} |
| themeModeVars | 主题模式变量配置 | Object | undefined |
| themePresetVars | 主题预设变量配置 | Object | undefined |
使用示例¶
1. 首先创建主题配置文件
// src/theme/businessComponentTheme.js
export const THEME_MODE_VARS = {
light: {
"--bams-page-bg": "#eef3f8",
"--bams-surface-bg": "#ffffff",
"--bams-text-color": "#223548",
"--bams-text-secondary": "#6b7c8f",
"--bams-border-color": "#e7ebee",
colorScheme: "light",
},
dark: {
"--bams-page-bg": "#0b1220",
"--bams-surface-bg": "#111827",
"--bams-text-color": "#e5edf7",
"--bams-text-secondary": "#94a3b8",
"--bams-border-color": "#253246",
colorScheme: "dark",
},
};
export const THEME_PRESET_VARS = {
"material.blue": {
"--bams-primary": "#0d6cbd",
"--bams-primary-soft": "color-mix(in srgb, #0d6cbd 12%, transparent)",
},
"material.teal": {
"--bams-primary": "#13c2c2",
"--bams-primary-soft": "color-mix(in srgb, #13c2c2 12%, transparent)",
},
};
2. 在组件中使用
<template>
<ComponentContainer :theme-mode-vars="THEME_MODE_VARS" :theme-preset-vars="THEME_PRESET_VARS">
<div class="title">业务组件标题</div>
<div class="content">业务组件内容</div>
</ComponentContainer>
</template>
<script setup>
import { ComponentContainer } from "@bams-app/components";
import { THEME_MODE_VARS, THEME_PRESET_VARS } from "../../theme/businessComponentTheme";
</script>
<style scoped lang="less">
.title {
color: var(--bams-text-color);
font-size: 16px;
font-weight: 500;
}
.content {
color: var(--bams-text-secondary);
font-size: 14px;
}
</style>
方法二:使用 LocalThemeContainer 组件¶
对于需要快速注入局部主题变量的场景,推荐使用 LocalThemeContainer 组件,它会自动处理变量计算和样式合并,并提供主题状态暴露。
Props 定义¶
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| containerStyle | 容器自定义样式 | Object | {} |
| themeModeVars | 主题模式变量配置 | Object | undefined |
| themePresetVars | 主题预设变量配置 | Object | undefined |
Events 定义¶
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| theme-change | 主题变化时触发 | themeStore.$state |
插槽暴露属性¶
| 属性 | 说明 |
|---|---|
| mode | 当前主题模式(light/dark) |
| preset | 当前主题预设 |
| resolvedMode | 解析后的模式(考虑系统默认) |
| modeClass | 模式对应的 CSS 类名 |
| presetClass | 预设对应的 CSS 类名 |
| localThemeVars | 生成的局部变量对象 |
| mergedStyle | 合并后的最终样式对象(含 containerStyle) |
使用示例¶
1. 首先创建主题配置文件
// src/theme/localThemeComponentTheme.js
export const THEME_MODE_VARS = {
light: {
"--bams-page-bg": "#eef3f8",
"--bams-surface-bg": "#ffffff",
"--bams-text-color": "#223548",
"--bams-text-secondary": "#6b7c8f",
"--bams-border-color": "#e7ebee",
colorScheme: "light",
},
dark: {
"--bams-page-bg": "#0b1220",
"--bams-surface-bg": "#111827",
"--bams-text-color": "#e5edf7",
"--bams-text-secondary": "#94a3b8",
"--bams-border-color": "#253246",
colorScheme: "dark",
},
};
export const THEME_PRESET_VARS = {
"material.blue": {
"--bams-primary": "#0d6cbd",
"--bams-primary-soft": "color-mix(in srgb, #0d6cbd 12%, transparent)",
},
"material.teal": {
"--bams-primary": "#13c2c2",
"--bams-primary-soft": "color-mix(in srgb, #13c2c2 12%, transparent)",
},
};
2. 在组件中使用
<template>
<LocalThemeContainer :theme-mode-vars="THEME_MODE_VARS" :theme-preset-vars="THEME_PRESET_VARS" @theme-change="handleThemeChange" v-slot="slotState">
<div class="title">业务组件标题</div>
<div class="content">业务组件内容</div>
<div class="info">当前模式:{{ slotState.mode }}</div>
</LocalThemeContainer>
</template>
<script setup>
import { LocalThemeContainer } from "@bams-app/theme";
import { THEME_MODE_VARS, THEME_PRESET_VARS } from "../../theme/localThemeComponentTheme";
const handleThemeChange = themeState => {
console.log("主题变化", themeState);
};
</script>
<style scoped lang="less">
.title {
color: var(--bams-text-color);
font-size: 16px;
font-weight: 500;
}
.content {
color: var(--bams-text-secondary);
font-size: 14px;
}
.info {
margin-top: 16px;
color: var(--bams-primary);
}
</style>
方法三:使用 useLocalThemeVars 工具¶
1. 首先创建主题配置文件
// src/theme/customComponentTheme.js
export const THEME_MODE_VARS = {
light: {
"--bams-page-bg": "#eef3f8",
"--bams-surface-bg": "#ffffff",
"--bams-text-color": "#223548",
"--bams-text-secondary": "#6b7c8f",
"--bams-border-color": "#e7ebee",
colorScheme: "light",
},
dark: {
"--bams-page-bg": "#0b1220",
"--bams-surface-bg": "#111827",
"--bams-text-color": "#e5edf7",
"--bams-text-secondary": "#94a3b8",
"--bams-border-color": "#253246",
colorScheme: "dark",
},
};
export const THEME_PRESET_VARS = {
"material.blue": {
"--bams-primary": "#0d6cbd",
"--bams-primary-soft": "color-mix(in srgb, #0d6cbd 12%, transparent)",
},
"material.teal": {
"--bams-primary": "#13c2c2",
"--bams-primary-soft": "color-mix(in srgb, #13c2c2 12%, transparent)",
},
};
2. 在组件中使用
<template>
<div class="custom-component" :style="localThemeVars">
<div class="title">自定义主题组件</div>
<div class="content">使用局部变量</div>
</div>
</template>
<script setup>
import { useLocalThemeVars } from "@bams-app/theme";
import { THEME_MODE_VARS, THEME_PRESET_VARS } from "../../theme/customComponentTheme";
// 使用 useLocalThemeVars 获取计算后的局部变量
const { localThemeVars } = useLocalThemeVars({
themeModeVars: THEME_MODE_VARS,
themePresetVars: THEME_PRESET_VARS,
});
</script>
<style scoped lang="less">
.custom-component {
background: var(--bams-page-bg);
color: var(--bams-text-color);
border: 1px solid var(--bams-border-color);
padding: 20px;
}
</style>
方法四:手动管理局部变量¶
如果需要更灵活的控制,也可以手动实现局部变量:
1. 首先创建主题配置文件
// src/theme/manualTheme.js
export const THEME_MODE_VARS = {
light: {
"--custom-bg": "#ffffff",
"--custom-text": "#223548",
colorScheme: "light",
},
dark: {
"--custom-bg": "#111827",
"--custom-text": "#e5edf7",
colorScheme: "dark",
},
};
export const getCustomThemeVars = (mode, presetConfig) => {
const currentMode = mode || "light";
const modeVars = THEME_MODE_VARS[currentMode];
return {
...modeVars,
"--custom-primary": presetConfig?.primary || "#0d6cbd",
};
};
2. 在组件中使用
<template>
<div class="custom-wrapper" :style="localThemeVars">
<!-- 组件内容 -->
</div>
</template>
<script setup>
import { computed } from "vue";
import { getThemePreset, useThemeState } from "@bams-app/theme";
import { THEME_MODE_VARS, getCustomThemeVars } from "../../theme/manualTheme";
const { preset, resolvedMode } = useThemeState();
const localThemeVars = computed(() => {
const presetConfig = getThemePreset(preset.value);
return getCustomThemeVars(resolvedMode.value, presetConfig);
});
</script>
<style scoped lang="less">
.custom-wrapper {
background: var(--custom-bg);
color: var(--custom-text);
}
</style>
最佳实践¶
- 始终使用
var(--bams-*)变量,不要直接写固定颜色值 - 优先使用语义化变量,如
--bams-text-color而非#333 - 避免过度自定义,尽量复用全局主题变量
- 局部变量仅在必要时使用,优先保持与全局主题一致
- 在弹出层组件中设置
getPopupContainer,确保弹出层继承局部变量 - 局部主题配置必须抽取到单独的
src/theme/目录文件中 - 主题配置文件命名规范:必须使用
xxxTheme.js格式
<template>
<div ref="containerRef" :style="localThemeVars">
<a-popover :get-popup-container="getPopupContainer"> 内容 </a-popover>
</div>
</template>
<script setup>
import { ref } from "vue";
const containerRef = ref(null);
const getPopupContainer = () => {
return containerRef.value || document.body;
};
</script>
注意事项¶
- 业务组件不应直接操作
useThemeStore,只通过 CSS 变量消费主题 - 局部变量会覆盖同作用域内的同名全局变量
- 如果没有启用主题功能(
VUE_APP_ENABLE_THEME未设置),将使用默认浅色主题变量
在 JavaScript 中获取 CSS 变量¶
除了在 CSS 中使用 var(--bams-*) 外,还可以在 JS 中动态获取这些变量。
API 概览¶
| 函数名 | 说明 |
|---|---|
getCssVar(varName, element?) |
获取单个 CSS 变量的值 |
getCssVars(varNames, element?) |
获取多个指定 CSS 变量的值 |
getAllCssVars(element?) |
获取所有 --bams- 开头的 CSS 变量 |
基础用法¶
import { getCssVar, getCssVars, getAllCssVars } from "@bams-app/theme";
// 获取单个变量(支持两种写法)
const primary = getCssVar("--bams-primary");
const primary = getCssVar("primary"); // 自动补全前缀
// 获取多个变量
const vars = getCssVars(["primary", "text-color", "success-color"]);
console.log(vars.primary);
console.log(vars.textColor); // 自动转换为驼峰命名
// 获取所有变量
const allVars = getAllCssVars();
在 Vue 组件中响应式使用¶
<script setup>
import { computed, watch } from "vue";
import { getCssVar, getAllCssVars, useThemeState } from "@bams-app/theme";
const { preset, resolvedMode } = useThemeState();
// 响应式获取单个变量
const primaryColor = computed(() => getCssVar("primary"));
// 响应式获取所有变量
const themeColors = computed(() => getAllCssVars());
// 监听主题变化
watch([preset, resolvedMode], () => {
console.log("主题已更新");
});
</script>
<template>
<div>
<p>当前主色: {{ primaryColor }}</p>
<div
:style="{
color: themeColors.textColor,
background: themeColors.pageBg,
}"
>
主题内容
</div>
</div>
</template>
变量名映射¶
CSS 变量使用 kebab-case(如 --bams-text-color),在 JS 返回对象中会自动转换为 camelCase(如 textColor)。