CSS 主题切换计划形式一: css / var()1. 定义2套主题色彩变量,属性选择器.root[theme='theme-red'] { --color-bg: rgba(255, 87, 87, 0.05); --font-text-color-title: rgba(255, 87, 87, 0.85); --font-text-color-base: rgba(255, 87, 87, 0.65); --primary: #ff5757;}.root[theme='theme-blue'] { --color-bg: rgba(0, 229, 255, 0.05); --font-text-color-title: rgba(0, 229, 255, 0.85); --font-text-color-base: rgba(0, 229, 255, 0.65); --primary: #00e5ff;}2. 主页面中增加属性theme, 值为相应的主题 theme-red 或 theme-blueimport React, { useEffect, useRef, useState } from 'react';import styles from './theme.less';interface ThemePageProps {}const themeMap = { 红色: 'theme-red', 蓝色: 'theme-blue',};const ThemePage: React.FC<ThemePageProps> = () => { const containerRef = useRef<HTMLDivElement>(null); const [theme, setTheme] = useState('theme-red'); useEffect(() => { containerRef.current?.setAttribute('theme', theme); }, [theme]); return ( <div className={styles.root} ref={containerRef}> <div className={styles.content}> <div className={styles.title}>我是题目</div> </div> <div className={styles.btnWrap}> {Object.entries(themeMap).map(([key, value]) => ( <span key={value} onClick={() => setTheme(value)}> {key} </span> ))} </div> </div> );};export default ThemePage;3. 应用主题变量.root { display: flex; flex-direction: column; background-color: var(--color-bg); height: 100vh;}.content { display: flex; align-content: center; justify-content: center; flex-direction: column; .title { text-align: center; font-size: 20px; color: var(--font-text-color-title); } .info { text-indent: 2em; font-size: 16px; color: var(--font-text-color-base); }}.btnWrap { display: flex; justify-content: center; margin-top: 20px; span { width: 120px; height: 32px; display: flex; align-items: center; justify-content: center; color: var(--primary); border: 2px solid var(--primary); background-color: #fff; border-radius: 10px; margin-right: 20px; cursor: pointer; &:hover { font-weight: bold; } }}4.编译后的文件.theme__root__3Nghz[theme='theme-red'] { --color-bg: rgba(255, 87, 87, 0.05); --font-text-color-title: rgba(255, 87, 87, 0.85); --font-text-color-base: rgba(255, 87, 87, 0.65); --primary: #ff5757;}.theme__root__3Nghz[theme='theme-blue'] { --color-bg: rgba(0, 229, 255, 0.05); --font-text-color-title: rgba(0, 229, 255, 0.85); --font-text-color-base: rgba(0, 229, 255, 0.65); --primary: #00e5ff;}.theme__root__3Nghz { display: flex; flex-direction: column; background-color: var(--color-bg); height: 100vh;}.theme__content__1gRQE { display: flex; align-content: center; justify-content: center; flex-direction: column;}.theme__content__1gRQE .theme__title__2W0ZV { text-align: center; font-size: 20px; color: var(--font-text-color-title);}.theme__content__1gRQE .theme__info__2c8iu { text-indent: 2em; font-size: 16px; color: var(--font-text-color-base);}.theme__btnWrap__2ZtlX { display: flex; justify-content: center; margin-top: 20px;}.theme__btnWrap__2ZtlX span { width: 120px; height: 32px; display: flex; align-items: center; justify-content: center; color: var(--primary); border: 2px solid var(--primary); background-color: #fff; border-radius: 10px; margin-right: 20px; cursor: pointer;}.theme__btnWrap__2ZtlX span:hover { font-weight: bold;}形式二 : less/ mixin1. 定义2套主题色彩变量, 用theme函数.theme(theme-red) { @color-bg: rgba(255, 87, 87, 0.05); @font-text-color-title: rgba(255, 87, 87, 0.85); @font-text-color-base: rgba(255, 87, 87, 0.65); @primary: #ff5757;}.theme(theme-blue) { @color-bg: rgba(0, 229, 255, 0.05); @font-text-color-title: rgba(0, 229, 255, 0.85); @font-text-color-base: rgba(0, 229, 255, 0.65); @primary: #00e5ff;}2.:global的形式全局范畴引入两套主题款式.theme-red 和 .theme-blue , 匹配全局的款式名:global(.theme-red) { .createTheme(theme-red);}:global(.theme-blue) { .createTheme(theme-blue);}3. 通过createTheme() 混入到每个作用范畴的less文件下.createTheme(@theme-name) { .theme(@theme-name); // 混入的主题色彩变量申明 .root { display: flex; flex-direction: column; background-color: @color-bg; height: 100vh; } .content { display: flex; align-content: center; justify-content: center; flex-direction: column; .title { text-align: center; font-size: 20px; color: @font-text-color-title; } .info { text-indent: 2em; font-size: 16px; color: @font-text-color-base; } } .btnWrap { display: flex; justify-content: center; margin-top: 20px; span { width: 120px; height: 32px; display: flex; align-items: center; justify-content: center; color: @primary; border: 2px solid @primary; background-color: #fff; border-radius: 10px; margin-right: 20px; cursor: pointer; &:hover { font-weight: bold; } } }}4. 在主页面中增加全局款式import React, { useEffect, useRef, useState } from 'react';import styles from './theme.less';interface ThemePageProps {}const themeMap = { 红色: 'theme-red', 蓝色: 'theme-blue',};const ThemePage: React.FC<ThemePageProps> = () => { const containerRef = useRef<HTMLDivElement>(null); const [theme, setTheme] = useState('theme-red'); useEffect(() => { document.documentElement.className = theme; }, [theme]); return ( <div className={styles.root} ref={containerRef}> <div className={styles.content}> <div className={styles.title}>我是题目</div> </div> <div className={styles.btnWrap}> {Object.entries(themeMap).map(([key, value]) => ( <span key={value} onClick={() => setTheme(value)}> {key} </span> ))} </div> </div> );};export default ThemePage;5. 编译后css文件红色主题
...