Skip to content

开发使用

TechUI 的主题系统通过 TuiProvider 将配置数据分发为 CSS 变量JavaScript 响应式状态。这意味着您可以在样式表、Vue 模板、逻辑代码甚至 Canvas 画布中无缝使用同一套语义化颜色。

在 CSS/Less 中使用

这是最常用的方式。当主题注册后,系统会自动将 JS 对象扁平化为 CSS 变量(Custom Properties)并注入到 :root 作用域中。

标准变量映射

变量名生成遵循 Kebab Case (短横线命名) 规则,将 JSON 对象的层级路径用 - 连接。

  • common.bg -> var(--common-bg)
  • primary.base -> var(--primary-base)
  • button.bg_hov -> var(--button-bg-hov)
  • scifi.header.hlite -> var(--scifi-header-hlite)

自动透明度衍生 (Opacity Variants)

为了方便开发,TechUI 在初始化主题时,会自动检测特定的属性,并生成 10% 到 90% 的透明度衍生变量。

命名规则:在原变量名后追加 _op + 1~9(代表 10%~90% 透明度)。

示例

  • var(--primary-base): 原始颜色 (100% 不透明)
  • var(--primary-base_op1): 10% 透明度
  • var(--primary-base_op5): 50% 透明度
  • var(--primary-base_op9): 90% 透明度

支持生成的范围: 并非所有变量都会生成透明度版本,系统仅针对以下核心高频使用的分类和属性进行生成,以避免 CSS 变量数量爆炸。

  • 支持的分类 (Category): common, button, input, tone, primary, success, info, warning, danger, emphasis
  • 支持的属性 (Key): bg, bd, weakest, weaker, weak, base, strong, stronger, strongest

样式编写示例

在 Vue 组件的 <style> 块中,您应该始终使用 var(--...) 而不是硬编码颜色值。

css
<style lang="less" scoped>
.my-card {
  /* 使用 10% 透明度的主色作为背景 */
  background-color: var(--primary-base_op1);
  /* 使用通用背景色 */
  background-color: var(--common-bg-layer);
  
  /* 使用通用边框色 */
  border: 1px solid var(--common-bd);
  /* 使用 50% 透明度的通用背景作为边框 */
  border: 1px solid var(--common-bg_op5);
  /* 使用主色作为文字颜色 */
  color: var(--primary-base);

  .title {
    /* 使用字体分级颜色 */
    color: var(--font-strong);
  }

  &:hover {
    /* 使用预定义的交互状态色 */
    border-color: var(--primary-strong);
    box-shadow: 0 0 10px var(--scifi-hlite); /* 引用科幻发光色 */
  }
}
</style>

提示:使用 CSS 变量的最大优势在于,当用户切换主题(如从浅色切到深色)时,浏览器会自动重绘所有引用了变量的区域,无需任何 JS 干预,性能极高。

在 JavaScript 中使用

在某些场景下,我们需要在逻辑中获取颜色值,例如:

  • 使用 Canvas / WebGL 绘图。
  • 配置 ECharts / Three.js / Cesium 等第三方库。
  • 动态计算行内样式。

TechUI 提供了全局注入函数 $tc (Theme Color) 来简化这一过程。

$tc 函数详解

$tc 函数支持两种获取模式:静态值响应式对象

函数签名$tc(path: String, isComputed: Boolean = false): String | ComputedRef<String>

1. 获取静态值 (一次性)

isComputedfalse(默认)时,返回当前时刻的颜色字符串。

javascript
import { inject, onMounted } from 'vue';

const { $tc } = inject('$global');

const initCanvas = () => {
  const ctx = canvas.getContext('2d');
  
  // 获取当前的 canvas 背景色
  // 返回值示例: "#ffffff" 或 "rgba(0,0,0,0.5)"
  ctx.fillStyle = $tc('common.bg'); 
  ctx.fillRect(0, 0, 100, 100);
};

注意:这种方式获取的颜色是非响应式的。如果用户切换了主题,Canvas 画布不会自动重绘,您需要监听主题变化并手动刷新。

2. 获取响应式对象 (推荐)

isComputedtrue 时,返回一个 Vue 的 ComputedRef 对象。当全局主题发生变化时,该对象的值会自动更新。

这在 Vue 的 computed 属性或 watch 侦听器中非常有用。

javascript
import { inject, computed } from 'vue';

const { $tc } = inject('$global');

// 创建一个响应式的样式对象
const cardStyle = computed(() => {
  return {
    // 必须使用 .value 获取计算属性的值
    backgroundColor: $tc('primary.weak', true).value,
    border: `1px solid ${$tc('primary.base', true).value}`
  };
});

处理颜色透明度

与 CSS 自动生成 _op 变量不同,在 JavaScript 中,为了保持逻辑的灵活性和减少内存占用,我们推荐使用 $c 工具函数来进行透明度处理,而不是去查找 _op 属性。

$c (TechUI Colors) 提供了强大的颜色操作能力。

示例代码

javascript
import { inject, computed } from 'vue';

// 注入全局服务和颜色工具
const { $tc, $c } = inject('$global');

// 场景 1: 获取带透明度的颜色字符串 (ECharts/Canvas 常用)
const initChart = () => {
  // 获取 primary.base 并赋予 30% 透明度
  // $c.fade(颜色值, 透明度 0-1)
  const areaColor = $c.fade($tc('primary.base'), 0.3); 
  
  console.log(areaColor); // 输出: "rgba(24, 144, 255, 0.3)"
};

// 场景 2: 在 Computed 中动态计算
const tagStyle = computed(() => {
  // 获取响应式的主题色
  const baseColor = $tc('success.base', true).value;
  
  return {
    color: baseColor,
    // 动态生成背景色:使用 10% 透明度的成功色
    backgroundColor: $c.fade(baseColor, 0.1),
    border: `1px solid ${$c.fade(baseColor, 0.2)}`
  };
});

监听主题变化

对于 ECharts 或 Mapbox 等需要显式调用 setOptionupdate 方法的库,建议配合 watch 使用。

javascript
import { inject, watch, ref } from 'vue';

const { $gTheme, $tc } = inject('$global');
const chartInstance = null;

// 监听主题名称的变化 ($gTheme)
watch($gTheme, () => {
  if (chartInstance) {
    // 重新获取最新的颜色值
    const newColor = $tc('chart.map.bg');
    
    // 更新第三方实例
    chartInstance.setOption({
      backgroundColor: newColor
    });
  }
});

最佳实践总结

  1. 优先 CSS:只要能用 CSS 解决的样式,务必使用 var(--...)。这是性能最好且维护成本最低的方式。
  2. 避免硬编码:永远不要在代码中写 #fffrgba(0,0,0,0.5)。如果现有主题中缺少某种颜色,请扩展自定义主题,而不是在组件中写死。
  3. 语义对齐
    • 做背景时用 common.bg_xxx
    • 写文字时用 font.xxx
    • 做按钮时用 button.xxx
    • 不要混用语义(例如不要把 button.bg 用作文字颜色),否则在反色主题(深色模式)下可能会出现“白底白字”的视觉 Bug。
  4. 使用 $tc 获取配置:除了颜色,主题中可能包含非颜色配置(如 scifi 中的透明度或线宽),同样可以使用 $tc\ 获取。