专栏名称: 前端大全
分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯
目录
相关文章推荐
湾区财经传媒  ·  小米SU7Ultra、15Ultra,深圳小 ... ·  11 小时前  
湾区财经传媒  ·  小米SU7Ultra、15Ultra,深圳小 ... ·  11 小时前  
前端之巅  ·  npm 够用吗?初创企业为何追捧这个 ... ·  2 天前  
51好读  ›  专栏  ›  前端大全

shadcn/ui:2024年最受欢迎的前端项目

前端大全  · 公众号  · 前端  · 2025-02-25 19:54

正文

之前发布的一篇文章里盘点了 2024 年最受欢迎的前端项目 ,其中 shadcn/ui 和去年一样再次成为2024年最热门的项目。这篇文章我们将对 shadcn/ui 进行简单介绍。

什么是Shadcn

官网:https://ui.shadcn.com/

Github:https://github.com/shadcn-ui/ui

在 shadcn 文档 https://ui.shadcn.com/docs,可以看到相关介绍:

  • shadcn/ui 不是组件库,而是可重复使用的组件的集合
  • 开发者可以将其 复制粘贴 到您的应用中,而不是作为依赖项进行安装

shadcn/ui 目前包括了常用的组件,并且在持续更新中。

接下来:我们初始化一个 Next.js 项目,然后使用 shadcn/ui 来理解上面的定义:

初始化Next.js项目

npx create-next-app@latest
Need to install the following packages:
[email protected]
Ok to proceed? (y) 
✔ What is your project named? … shadcn-ui-example
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /shadcn-ui-example.

安装 shadcn/ui

npx shadcn@latest init -d

将组件添加到项目

npx shadcn@latest add button

在 package.json 中我们并没有找到关于 button 的依赖:

而是在 shadcn-ui-example/components/ui 目录下,生成了一个 button.jsx。

button.jsx 具体代码如下:

import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva } from "class-variance-authority";

import { cn } from "@/lib/utils"

const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
  {
    variants: {
      variant: {
        default:
          "bg-primary text-primary-foreground shadow hover:bg-primary/90",
        destructive:
          "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
        outline:
          "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
        secondary:
          "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
        ghost"hover:bg-accent hover:text-accent-foreground",
        link"text-primary underline-offset-4 hover:underline",
      },
      size: {
        default"h-9 px-4 py-2",
        sm"h-8 rounded-md px-3 text-xs",
        lg"h-10 rounded-md px-8",
        icon"h-9 w-9",
      },
    },
    defaultVariants: {
      variant"default",
      size"default",
    },
  }
)

const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
  const Comp = asChild ? Slot : "button"
  return (
    (<Comp
    className={cn(buttonVariants({ variantsizeclassName }))}
  ref={ref}
  {...props} />
)
  );
})
Button.displayName = "Button"

export { Button, buttonVariants }

可以看到 shadcn/ui 直接把组件代码增加的了我们的项目中。这样的好处显而易见,对比我们使用类似 Ant Design 之类的组件库,如果想要高度定制样式 shadcn/ui 会更容易一些。我们把button添加到页面中运行看一下效果:

"use client";
import { Button } from "@/components/ui/button";

export default function Home({
  return (
    <div className="flex w-full h-full items-center justify-center">
      <Button>Click meButton>
    div>

  );
}

我们再添加一个 Accordion 组件:

npx shadcn@latest add accordion
"use client"

import * as React from "react"
import * as AccordionPrimitive from "@radix-ui/react-accordion"
import { ChevronDown } from "lucide-react"

import { cn } from "@/lib/utils"

const Accordion = AccordionPrimitive.Root

const AccordionItem = React.forwardRef(({ className, ...props }, ref) => (
  <AccordionPrimitive.Item ref={ref} className={cn("border-b", className)} {...props} />
))
AccordionItem.displayName = "AccordionItem"

const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => (
  <AccordionPrimitive.Header className="flex">
    <AccordionPrimitive.Trigger
      ref={ref}
      className={cn(
        "flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline text-left [&[data-state=open]>
svg]:rotate-180",
        className
      )}
      {...props}>
      {children}
      <ChevronDown
        className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" />

    AccordionPrimitive.Trigger>
  AccordionPrimitive.Header>

))
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName

const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => (
  <AccordionPrimitive.Content
    ref={ref}
    className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
    {...props}>

    <div className={cn("pb-4 pt-0", className)}>{children}div>
  AccordionPrimitive.Content>

))
AccordionContent.displayName = AccordionPrimitive.Content.displayName

export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }

这次在 package.json 中添加了 radix-ui 相关依赖:

"@radix-ui/react-accordion""^1.2.2"

什么是radix-ui

官网:https://www.radix-ui.com

Github:https://github.com/radix-ui/primitives

Radix 提供了无样式、访问性友好的 React 原子级组件,允许开发者在完全掌控样式的情况下构建自己的设计系统。

Radix 的核心功能

Unstyled

Radix UI 组件本身不带有任何设计或样式,它只提供了基础的结构和交互功能。开发者可以完全自定义样式,适应自己的设计需求。

Stateless

Radix 组件不维护内部状态,而是依赖外部传入的 props 来管理组件的状态。

Accessibility

Radix UI 对可访问性有很高的关注,所有组件都遵循 WCAG(Web Content Accessibility Guidelines)标准。

高度可定制

Radix UI 组件提供了许多灵活的 API,可以根据项目需求进行定制。

原子化

Radix 提供的组件是高度模块化的,可以按需引入。每个组件都只处理单一的功能,避免了将多个功能捆绑到一起的复杂性,增强了代码的复用性和可维护性。

Shadcn、Radix UI、Ant Design对比

特性 Shadcn Radix UI Ant Design
定位 基于 Radix 的功能,提供预置样式 原子级组件逻辑,无样式,提供基础功能 全功能企业级设计系统
可定制性 极高,依赖 Tailwind CSS,完全控制样式 极高,无内置样式,自定义完全由开发者负责 中等,通过主题和配置文件进行定制
开发效率 较高,灵活但需要搭配 Tailwind CSS 较低,需花时间自定义样式和集成其他工具 很高,组件丰富且开箱即用
适用场景 需要灵活样式控制的项目,尤其是基于 Tailwind CSS 的应用 需要完全定制的应用,适合追求细节和功能控制的场景 复杂、正式的企业级系统或快速交付的商业项目

Shadcn 定制主题

在 https://ui.shadcn.com/themes 选择主题然后点击 Copy code 即可:


@layer base {
  :root {
    --background: 0 0100%;
    --foreground: 0 03.9%;
    --card: 0 0100%;
    --card-foreground: 0 03.9%;
    --popover: 0 0100%;
    --popover-foreground: 0 03.9%;
    --primary: 0 72.250.6%;
    --primary-foreground: 0 85.797.3%;
    --secondary: 0 096.1%;
    --secondary-foreground: 0 09%;
    --muted: 0 096.1%;
    --muted-foreground: 0 045.1%;
    --accent: 0 0






请到「今天看啥」查看全文