在 Vue3 中如何实现亮色 / 暗色主题切换?
Vue3 同样推荐「CSS 变量 + 根节点 class + provide/inject」。
1. CSS 变量定义主题(同 React 思路)
:root { --bg: #fff; --text: #111; }
:root.dark { --bg: #111; --text: #fff; }2. 用 Composition API + provide/inject 管理
// useTheme.js
import { ref, watch } from 'vue'
export function useTheme() {
const theme = ref(localStorage.getItem('theme') || 'light')
watch(theme, (val) => {
document.documentElement.className = val
localStorage.setItem('theme', val)
}, { immediate: true })
const toggle = () => {
theme.value = theme.value === 'light' ? 'dark' : 'light'
}
return { theme, toggle }
}<!-- App.vue -->
<script setup>
import { provide } from 'vue'
import { useTheme } from './useTheme'
const { theme, toggle } = useTheme()
provide('theme', theme)
provide('toggleTheme', toggle)
</script>
<template>
<button @click="toggle">切换主题(当前:{{ theme }})</button>
<slot />
</template>注意
- 子组件通过
inject('theme')读取,无需逐层传 props。 - 组件样式全部走 CSS 变量,不要在
<style>里写死颜色,否则换肤失效。 - 若用 scoped 样式,CSS 变量仍作用在根作用域,不受影响。