玩转TinyVue全局配置主题定制工具实战

3 阅读8分钟

玩转 TinyVue 全局配置:主题定制 + 工具实战

作为一个前端开发者,你有没有经历过这种场景——产品经理拿着一个设计稿走过来,微笑着说:"这个页面能不能换个主题色?就改一下,很简单的。"你心里咯噔一下,想起了那几百个散落在各处的 CSS 变量……

别慌,今天咱们就来聊聊 TinyVue 的全局配置和主题定制,让你在面对"换个主题"这种需求时,能够优雅地掏出 TinyThemeTool,像个老中医一样精准施治。

一、全局配置的"大管家"——ConfigProvider

1.1 为什么需要全局配置?

想象一下,你家装修完了,突然想换风格——从北欧极简换成中式古典。如果每个房间都得单独改,那简直是噩梦。但如果有个"中央控制系统",一键切换全屋风格呢?

TinyVue 的 ConfigProvider 就是这个"中央控制系统"。它负责全局配置,让你不用逐个组件去设置样式和行为。

1.2 ConfigProvider 的基本用法

ConfigProvider 组件用于全局配置,它的 key 为 'cmp-frame-style'。你可以通过它配置设计规范(design)、主题等。

<template>
  <tiny-config-provider :design="designConfig">
    <div id="app">
      <!-- 你的整个应用都在 ConfigProvider 的管辖范围内 -->
      <tiny-button>点我</tiny-button>
      <tiny-input v-model="value"></tiny-input>
    </div>
  </tiny-config-provider>
</template>

<script>
import { ConfigProvider } from '@opentiny/vue'

export default {
  components: {
    TinyConfigProvider: ConfigProvider
  },
  data() {
    return {
      value: '',
      designConfig: {
        // 设计规范配置
      }
    }
  }
}
</script>

重点提醒ConfigProvider 必须包裹在应用的根节点外层,就像你家的总配电箱必须装在总开关那里一样。装在某个小房间的开关上,那只能控制那个房间——虽然也能用,但全局配置的威力就发挥不出来了。

二、主题定制——TinyThemeTool 大揭秘

2.1 ThemeData:主题的数据身份证

TinyVue 的主题定制核心是 TinyThemeTool 类。每个主题都有一个"身份证"——ThemeData 接口,它包含以下信息:

interface ThemeData {
  id: string        // 主题唯一标识,就像身份证号
  name: string      // 主题英文名,方便代码引用
  cnName: string    // 主题中文名,方便产品经理念叨
  data: Record<string, string>  // CSS 变量覆盖,核心改造区
  css: string       // CSS 规则覆盖,兜底改造区
}

其中 data 是最常用的字段,它就是一堆 CSS 变量的键值对覆盖。比如你想把按钮的主色调从蓝色换成绿色,改几个变量就搞定了,不用到处去搜 background-color: blue

2.2 CSS 变量的前世今生——从 --ti- 到 --tv-

这里有个重要版本区分,老司机们请注意:

  • v3.19.0 之前:CSS 变量使用 --ti- 前缀,这是"老派风格"
  • v3.19.0 开始:切换为 Opentiny Design 新风格,CSS 变量使用 --tv- 前缀

这就像手机号从 11 位升级到了——好吧,手机号还是 11 位。但 TinyVue 的风格升级是真的,而且更规范了。

/* 旧风格 --ti- 前缀(v3.19.0之前) */
:root {
  --ti-button-primary-bg: #1890ff;
}

/* 新风格 --tv- 前缀(v3.19.0+) */
:root {
  --tv-Button-primary-bg-color: #1890ff;
}

所以你在定制主题的时候,一定要先确认你用的是哪个版本!用旧版本的变量名配新版本的组件,就像拿着 3G 手机去连 5G 基站——信号不对,效果为零。

2.3 官方主题:不用自己调,现成的"套餐"

TinyVue 提供了几款官方主题,就像饭店的套餐一样,直接点就行:

主题名说明
默认主题基础样式,清清爽爽
tinyInfinityTheme无限主题,科技感十足
tinyAuroraTheme极光主题,浪漫氛围
tinySmbThemeSMB主题,商务风格

切换官方主题的方式很简单:

import { TinyThemeTool } from '@opentiny/vue-theme'

// 切换到极光主题
TinyThemeTool.changeTheme('tinyAuroraTheme')

一行代码,整个应用的风格就变了。产品经理看了直呼:"这也行?"——行,当然行,这就是 TinyVue 的实力。

2.4 自定义主题:我的风格我做主

如果你觉得官方主题都不够个性,那就自己来。自定义主题其实就是写一份 ThemeData

import { TinyThemeTool } from '@opentiny/vue-theme'

const myCustomTheme = {
  id: 'my-awesome-theme',
  name: 'awesomeTheme',
  cnName: '超赞主题',
  data: {
    '--tv-Button-primary-bg-color': '#e74c3c',     // 红色主按钮
    '--tv-Button-primary-text-color': '#ffffff',    // 白色文字
    '--tv-Input-border-color': '#e74c3c',           // 红色边框输入框
    '--tv-Link-text-color': '#e74c3c',              // 红色链接
    '--tv-Checkbox-checked-color': '#e74c3c',       // 红色选中色
  },
  css: ''
}

// 应用自定义主题
TinyThemeTool.changeTheme(myCustomTheme)

你看,就几行配置,你的应用就变成了"红色狂热"风格。当然,实际项目中的主题定制会更复杂,但原理是一样的——找到你想改的 CSS 变量,给它新值就行。

小技巧:怎么知道有哪些 CSS 变量可以改?打开浏览器开发者工具,选中一个组件元素,在 Styles 面板里搜索 --tv-,就能看到所有相关的变量。这比翻文档快多了——虽然翻文档也是一种修行。

三、深色模式——夜间coding的救星

3.1 开启深色模式

从 v3.22.0 开始,TinyVue 正式支持深色模式。这对于我们这些深夜还在写代码的程序员来说,简直是护眼神器。

开启步骤只有两步:

第一步:引入深色模式样式文件

// 在入口文件引入深色模式样式
import '@opentiny/vue-theme/dark-theme-index.css'

第二步:在 html 根元素添加 dark 类名

<html class="dark">
  <!-- 你的应用 -->
</html>

就这么简单,两步搞定。比你去淘宝买个防蓝光眼镜快多了。

3.2 动态切换深色/浅色模式

当然,你不能让用户一直待在暗黑模式里——白天看深色界面,就像大中午戴墨镜,也不太合适。所以我们需要动态切换:

function toggleDarkMode(isDark) {
  const html = document.documentElement
  if (isDark) {
    html.classList.add('dark')
  } else {
    html.classList.remove('dark')
  }
}

// 在 Vue 组件中使用
export default {
  data() {
    return {
      isDark: false
    }
  },
  methods: {
    switchMode() {
      this.isDark = !this.isDark
      toggleDarkMode(this.isDark)
    }
  }
}

你甚至可以结合系统偏好来实现自动切换:

// 监听系统深色模式偏好
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
mediaQuery.addEventListener('change', (e) => {
  toggleDarkMode(e.matches)
})
// 初始化时也判断一次
toggleDarkMode(mediaQuery.matches)

这样你的应用就能跟着系统自动切换了,用户体验直接拉满。

四、微前端场景下的样式挂载

如果你的项目用了微前端架构(比如 qiankun),样式挂载是个不得不考虑的问题。在微前端场景下,你需要将样式挂载到 ShadowRoot,而不是默认的 document.head。

为什么要这样做?因为微前端子应用的样式如果直接挂到 document.head,可能会和其他子应用或主应用的样式冲突——就像几个室友共用一个衣柜,衣服混在一起就容易穿错。

// 微前端场景下的样式挂载
import { TinyThemeTool } from '@opentiny/vue-theme'

// 将样式挂载到 ShadowRoot
const shadowRoot = document.querySelector('#sub-app').shadowRoot
TinyThemeTool.setMountTarget(shadowRoot)

这样每个子应用的样式就各归各的"衣柜"了,互不干扰。

五、实战:从零搭建一个定制主题的项目

让我们把前面的知识串起来,做一个完整的实战案例。

5.1 项目初始化

# 创建 Vue3 项目
npm create vite@latest my-tiny-app -- --template vue

# 安装 TinyVue
cd my-tiny-app
npm install @opentiny/vue@3

5.2 入口文件配置

// main.js
import { createApp } from 'vue'
import App from './App.vue'

// 引入深色模式样式(可选)
import '@opentiny/vue-theme/dark-theme-index.css'

// 引入 TinyVue 全局配置组件
import { ConfigProvider } from '@opentiny/vue'

const app = createApp(App)
app.component('TinyConfigProvider', ConfigProvider)
app.mount('#app')

5.3 App 组件——全局配置 + 主题切换

<template>
  <tiny-config-provider>
    <div :class="{ dark: isDark }" class="app-container">
      <header class="app-header">
        <h1>我的超赞应用</h1>
        <tiny-button @click="toggleDark">切换模式</tiny-button>
        <tiny-button @click="switchTheme('tinyAuroraTheme')">极光主题</tiny-button>
        <tiny-button @click="switchTheme(myTheme)">自定义主题</tiny-button>
      </header>
      <main>
        <tiny-button type="primary">主按钮</tiny-button>
        <tiny-input v-model="inputVal" placeholder="试试输入"></tiny-input>
      </main>
    </div>
  </tiny-config-provider>
</template>

<script>
import { TinyThemeTool } from '@opentiny/vue-theme'
import { Button, Input, ConfigProvider } from '@opentiny/vue'

const myTheme = {
  id: 'my-red-theme',
  name: 'redTheme',
  cnName: '红色狂热',
  data: {
    '--tv-Button-primary-bg-color': '#e74c3c',
    '--tv-Button-primary-text-color': '#ffffff',
    '--tv-Input-border-color': '#e74c3c',
  },
  css: ''
}

export default {
  components: {
    TinyButton: Button,
    TinyInput: Input,
    TinyConfigProvider: ConfigProvider
  },
  data() {
    return {
      isDark: false,
      inputVal: '',
      myTheme
    }
  },
  methods: {
    toggleDark() {
      this.isDark = !this.isDark
      const html = document.documentElement
      if (this.isDark) {
        html.classList.add('dark')
      } else {
        html.classList.remove('dark')
      }
    },
    switchTheme(theme) {
      TinyThemeTool.changeTheme(theme)
    }
  }
}
</script>

5.4 效果验证

运行项目后,你就可以:

  1. 点击"切换模式"按钮,体验深色/浅色模式的切换
  2. 点击"极光主题",感受官方极光主题的魅力
  3. 点击"自定义主题",看看你的红色狂热效果

整个过程丝滑流畅,没有任何卡顿——就像你在游戏里一键换装一样。

六、常见坑点和避坑指南

坑点原因解决方案
主题切换没效果版本不对,用了 --ti- 变量配 --tv- 组件确认版本,使用对应前缀
ConfigProvider 包裹范围太小只包了部分组件包裹到应用根节点
深色模式不生效没引入 dark-theme-index.css在入口文件引入
自定义主题变量名写错拼写错误或用了不存在的变量用开发者工具查看实际变量名
微前端样式冲突样式挂载到了 document.head挂载到 ShadowRoot

七、总结

TinyVue 的全局配置和主题定制体系,就像一个精心设计的装修方案——有总控中心(ConfigProvider),有专业工具(TinyThemeTool),有现成套餐(官方主题),也有 DIY 选项(自定义主题),还有夜间模式(深色模式)。

掌握了这些,你面对"换个主题"的需求时,就可以从容地说:"没问题,一分钟搞定。"——而不是默默打开搜索,在几百个文件里找那该死的 background-color

记住几个关键点:

  1. ConfigProvider 是全局配置的入口,要包在根节点外层
  2. TinyThemeTool 是主题定制的利器,ThemeData 是主题的身份证
  3. 注意版本区分,v3.19.0+ 用 --tv- 前缀,旧版用 --ti-
  4. 深色模式从 v3.22.0 开始支持,两步开启
  5. 微前端场景要挂载到 ShadowRoot,避免样式冲突

好了,今天的内容就到这里。下次产品经理再来找你换主题,你就可以微笑着说——"我用的 TinyVue,换主题只需一行代码。"


🏠 TinyVue 官网:opentiny.design 📦 GitHub 仓库:github.com/opentiny/ti…