什么是shadcn/ui?

971 阅读4分钟

前言

因为要用Nextjs对公司原来的登录项目进行重构,讲到要用shadcn UI,所以调研一下,看下shadcn UI的文档,学习下使用,以下就是我学习shadcn UI的一个简单的入门文章。

什么是shadcn UI ?

Shadcn UI 实际上不是一个组件库或 UI 框架。相反,根据文档,它是“一个可重用组件的集合,我们可以复制并粘贴到我们的应用程序中。”

Shadcn UI 构建于 Tailwind CSS 和 Radix UI 之上,目前支持 Next.js、 Gatsby、 Remix、 Astro、 Laravel 和 Vite等。

截止我写这篇文章,这个项目在github上的star有75.1k,我查看的一些博客都说这个项目现在很流行,但这应该是在国外,国内我倒是没有听到大家在讨论它或者将它用到了生产的项目上。

为什么要用shadcn/ui?

我也是带着这个疑惑开始了解shadcn/ui,关于到底要不要使用shadcn/ui,可以从以下这几点去考虑自己到底需不需要开始使用shadcn/ui:

应该使用shadcn/ui的一些理由:

  • 提供设计精美的部件
  • 组件数量多,包含各种类型的组件
  • 样式上采用了tailwind css的方法

不应该使用shadcn/ui的一些理由:

  • 组件的维护和修改组件的成本大
  • 组件捆绑可能会产生性能问题
  • 需要有tailwind css的基础

除了上面提到的一些理由,如果想要用shadcn ui开始构建项目,还要分析下我们项目的需求,以及开发时间和进度要求,人员的配置等。

使用shadcn/ui创建项目

我这里只是写一个简单的步骤,只是告诉你怎么在一个Nextjs的项目里面使用shadcn/ui,至于更深入的使用以及使用过程中的一些其他的问题,这里暂时不考虑

首先,创建一个Nextjs的项目

npx create-next-app@latest my-app --typescript --tailwind --eslint

创建Nextjs的时候的一些配置,按你的需要去进行配置,每个配置具体的含义可以去看下Nextjs的文档

在创建好Nextjs项目之后,进入到Nextjs项目里面,然后再执行

npx shadcn@latest init

在执行上面命令的时候,会有一些shadcn的配置问题,如下图所示

截屏2024-11-26 下午4.47.39.png 这几个问题都是关于基础配置和样式的配置,不同配置的具体含义,还是要去官网查看,我目前是选择了这上图所示的配置

执行完npx shadcn之后,我们就可以在项目里看到,项目下面多了一个components文件夹

接下来,我们要在我们的项目里面添加我们将会用到的一些组件,我这里先添加了一个button的组件

npx shadcn@latest add button

执行这个命令之后,我们的components文件夹下会多出来一个叫button.tsx的文件,我们来看下这个文件里面的内容

import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } 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",
    },
  }
)

export interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  asChild?: boolean
}

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

export { Button, buttonVariants }

从它的引入来看,引入了@radix-ui/react-slot,允许子组件通过 asChild 属性改变其根元素的渲染标签。引入了class-variance-authority,用于管理组件的样式变体和默认样式。

在项目中使用这个button组件

import { Button } from "@/components/ui/button"

export default function Home() {
  return (
    <Button variant="outline">Button</Button>
  );
}

总结

如果想要在项目里面使用shadcn/ui,还是得好好的分析下自己当前的业务和需求,确定下有没有这个需要,前期也要预留一些时间去学习一些前置的知识,包括shadcn/ui中的一些配置。