欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 基于 shadcn + tailwind 4.1的页面主题切换方案(附源码)

基于 shadcn + tailwind 4.1的页面主题切换方案(附源码)

2025/6/18 10:54:56 来源:https://blog.csdn.net/kaituozhe345/article/details/148712690  浏览:    关键词:基于 shadcn + tailwind 4.1的页面主题切换方案(附源码)

项目不算复杂,文章不想看的源码可自取
github地址:shadcn-tailwind-theme-switcher

介绍

从0开始开发一个基于shadcn和tailwindcss v4.1的主题切换功能。

查看效果:页面预览

如何刚好是你想要的再读不迟 ~

几个作用。现在很多项目都有主题切换功能,但搞的太复杂理不清其中的逻辑;另外,大家混用shadcn/tailwind常常搞不清二者的功能边界;最后tailwind从3到4也有很多变化。借此梳理一下,让内心稍微平静一点。

创建项目

使用vite工具快速创建一个react项目,以该项目作为基础逐步丰富代码
个人感觉pnpm四个字母打字时有点别扭,就配成p了,下文所有的p指定代表pnpm

  • p create vite . 在当前目录使用vite创建项目,后面选择react typescript
  • p install 安装依赖
  • p dev 启动服务
  • 点击控制台url打开页面,上面这几步无任何障碍,搭建react项目首选vite很丝滑。

引入tailwindCSS

  • p install tailwindcss @tailwindcss/vite
  • 添加插件给vite
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({plugins: [tailwindcss(),],
})
  • 创建 src/global.css,导入tailwind默认能力。(v4之前要分别导入,现在一句顶三句)
@import "tailwindcss";
  • 在App.tsx中引入该 gloabl.css,后面就可以愉快的使用tailwind了
function App() {return (<><h1 className="text-3xl font-bold text-red-500">Hello world!</h1></>)
}
  • 更多的tailwind知识如变量、样式覆盖等可以看看现成的文章 这篇

增加深/浅模式切换功能

tailwindcss v4 中采用了 CSS-first 配置方式,可以直接在 CSS 文件中配置所有内容,理论上不需要有tailwind.config.ts文件了,但依旧保持对该文件的支持(向下兼容)。鉴于现在大部分资料都基于tailwind.config.ts,彻底删除可能会带来不小的额外成本(需要查css中如何对齐config的能力)。

添加tailwind darkMode

  • 创建tailwind.config.ts文件,增加 darkMode: 'class'
export default {darkMode: 'class',content: ["./index.html","./src/**/*.{js,ts,jsx,tsx}",],theme: {extend: {colors: {green: {100: '#FF0000',},red: {100: '#00FF00',},},},},plugins: [],
}
  • 设置完上述操作后,如果页面中使用了bg: 开头的样式,那当设置<html class="dark"></html> 时该样式便会生效。

介绍shadcn/ui

  • shadcn/ui 跟常规ui库最大的差异是shadcn/ui会把你需要的组件代码直接copy到你的项目中,而不是增加npm包,所以他的导入方式不是pnpm add shadcn/ui。
  • 但使用后会发现,package.json中增加了很多 @radix-ui/ 开头多包,radix-ui是一个只提供基础能力但不提供样式的ui库,即无头headless样式库,shadcn是在它的基础上使用tailwind语法实现了自己的组件样式。
  • 要不要纠结radix-ui的引入破坏了shadcn声称的把代码权限完全交给开发者,而不是给一个npm包理念。个人觉得99%的场景下不用纠结,因为radix-ui基于WAI-ARIA 设计模式只实现了最基础的能力,把样式的自定义完全留给开发者。

安装shadcn/ui

  • 在 tsconfig.json 和 tsconfig.app.json 中增加下面配置
{ "compilerOptions": { // ... "baseUrl": ".", "paths": { "@/*": [ "./src/*" ] } // ... }}
}	
  • 在vite.config.ts 中增加
resolve: { alias: { "@": path.resolve(__dirname, "./src"), }, 
}
  • p dlx shadcn@latest init 初始化shadcn,p dlx 等价于 npx

    • 初始化后会创建 components.json
    • 还会自动找到tailwind到样式文件,global.css,然后插入一堆默认的样式变量,如下:
      在这里插入图片描述
  • 在模式切换中tailwind和shadcn的作用:

    • tailwind可以自动根据根目录的dark类,切换bg: 开头的变量。自己在写样式时如果需要给暗黑模式下一个单独的样式,就需要写很多bg:xxx
    • shadcn库里的组件,本身就实现了对不同主题下的风格可变性,就是通过css变量实现的。简单讲,shadcn所有组件的颜色都是走全局变量的(不会写死),当切主题时只要改变这些变量即可。当然这些变量都已经暴露出来了很方便修改。

增加模式切换逻辑

  • 增加一个mode-toggle.tsx
import { Moon, Sun } from "lucide-react"
import { Button } from "@/shadcn/components/button"
import {DropdownMenu,DropdownMenuContent,DropdownMenuItem,DropdownMenuTrigger,
} from "@/shadcn/components/dropdown-menu"
import { useTheme } from "@/theme/theme-provider"
export function ModeToggle() {const { setTheme } = useTheme()return (<DropdownMenu><DropdownMenuTrigger asChild><Button variant="outline" size="icon"><Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" /><Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" /><span className="sr-only">切换主题</span></Button></DropdownMenuTrigger><DropdownMenuContent align="end"><DropdownMenuItem onClick={() => setTheme("light")}>明亮</DropdownMenuItem><DropdownMenuItem onClick={() => setTheme("dark")}>暗黑</DropdownMenuItem><DropdownMenuItem onClick={() => setTheme("system")}>系统</DropdownMenuItem></DropdownMenuContent></DropdownMenu>)
}
  • 增加 theme-provider.tsx 添加具体的切换逻辑
  • 然后在主文件,main.tsx 和 App.tsx 调用上述代码即可

增加颜色主题模式功能

  • 色系变化的核心逻辑:
    • global.css 先看下该文件下的配置,重点是其中的 :root[data-theme="rose"] .dark[data-theme="rose"] :root[data-theme="green"] .dark[data-theme="green"] 这些作用域下各自定义了响应色系下的变量,当切换色系时只需动态改变<html data-theme="rose"></html> 里面的颜色属性即可
  • 从shadcn/ui themes 这里直接copy出自己想要的色系对应的变量,放到global.css里。
  • 新增 theme-toggle.tsx 文件,处理色系的选择事件。
  • 再在 theme-provider.tsx 添加色系主题相关的变动逻辑即可。

参考:

  • 听说你还不会 Tailwind CSS(进阶·下篇) 系列文章含六篇,读完可快速了解tailwind大致能力,缺点是在目前tailwindcss v4版本下稍显过时,还好问题不大。
  • Tailwind CSS 文档-中文 还是官网文档来的给力
  • Shadcn UI 中文文档 推荐直接看官网,社区文章没看到太好的。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词