react库:class-variance-authority

news2025/6/3 8:18:50

文章目录

  • 前言
    • 一、cva 的核心作用
    • 二、代码逐层解析
    • 参数详解
      • 基础样式(第一个参数):
      • variant:定义颜色/风格变体(如 default、destructive)。
      • size:定义尺寸变体(如 sm、lg)。
      • 默认变体(defaultVariants):
    • 三、动态生成 className
    • 四、为什么使用 cva?
      • 传统 CSS 的问题
      • cva 的优势
  • 五、与其他工具对比
  • 六、完整工作流程
  • 七、关键代码片段解析
        • 应用场景:当需要将 <Button> 渲染为 <a> 或其他标签时:
      • cn 工具
  • 总结


前言

cva 是class-variance-authority库的核心 API,它是一种用于动态生成多变体 CSS 类名的工具,专门为处理组件样式的复杂变体(Variant)组合而设计。

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-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
  {
    variants: {
      variant: {
        default:
          "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
        destructive:
          "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
        outline:
          "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
        secondary:
          "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
        ghost:
          "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-9 px-4 py-2 has-[>svg]:px-3",
        sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
        lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
        icon: "size-9",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

function Button({
  className,
  variant,
  size,
  asChild = false,
  ...props
}: React.ComponentProps<"button"> &
  VariantProps<typeof buttonVariants> & {
    asChild?: boolean
  }) {
  const Comp = asChild ? Slot : "button"

  return (
    <Comp
      data-slot="button"
      className={cn(buttonVariants({ variant, size, className }))}
      {...props}
    />
  )
}

export { Button, buttonVariants }

一、cva 的核心作用

cva 允许你通过结构化配置定义组件的多种样式变体(如不同颜色、尺寸),然后根据传入的 variant 和 size 等参数动态生成最终的 className 字符串。

二、代码逐层解析

cva 基础调用

const buttonVariants = cva(
  "基础样式类", // 所有变体共享的公共样式
variants: { / 变体定义 / },

    defaultVariants: { / 默认变体 / }
);

参数详解

基础样式(第一个参数):

    "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"

这些样式会应用到所有按钮变体上(如布局、禁用状态、焦点效果等)。
变体配置(variants 对象):

variant:定义颜色/风格变体(如 default、destructive)。

        variant: {
      default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
      destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90",
      outline: "border bg-background shadow-xs hover:bg-accent",
      // ...其他变体

size:定义尺寸变体(如 sm、lg)。


     size: {
      default: "h-9 px-4 py-2 has-[>svg]:px-3",
      sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
      // ...其他尺寸

默认变体(defaultVariants):

当不传参数时使用的默认值:

    defaultVariants: {
    variant: "default", // 默认使用 default 颜色变体
    size: "default"     // 默认使用 default 尺寸

三、动态生成 className

通过 buttonVariants({ variant, size, className }) 动态计算:
// 示例1:生成默认按钮样式

buttonVariants({}); 

// 输出: “基础样式类 + default变体样式 + default尺寸样式”

// 示例2:生成 destructive 小号按钮

buttonVariants({ variant: "destructive", size: "sm" });

// 输出: “基础样式类 + destructive变体样式 + sm尺寸样式”

// 示例3:合并外部传入的 className

buttonVariants({ variant: "outline", className: "custom-class" });

// 输出: “基础样式类 + outline变体样式 + default尺寸样式 + custom-class”

四、为什么使用 cva?

传统 CSS 的问题

手动拼接类名易出错:{variant} {size} ${className}

难以维护多变体组合逻辑。

cva 的优势

类型安全:通过 VariantProps 自动推断 variant 和 size 的合法值。

结构化配置:清晰分离基础样式、变体和默认值。

原子化组合:避免样式冲突,支持 Tailwind CSS 等工具。

五、与其他工具对比

工具特点
cva专注变体组合,轻量级,适合组件库开发
Tailwind CSS提供原子类,但变体组合需手动处理
Styled ComponentsCSS-in-JS 方案,更适合动态样式(如基于 props 的样式)
CSS Modules局部作用域,但变体逻辑仍需手动编写

六、完整工作流程

定义变体:用 cva 配置组件的所有可能样式组合。

组件封装:通过 Button 组件暴露变体参数(variant、size)。

动态渲染:根据传入参数生成最终 className,并合并外部类名。

类型提示:利用 VariantProps 自动生成 TypeScript 类型。

七、关键代码片段解析

asChild 模式

const Comp = asChild ? Slot : "button";

Slot(来自 @radix-ui/react-slot):允许将按钮的样式和属性传递给子组件,实现样式透传。

应用场景:当需要将 渲染为 或其他标签时:
   <Button asChild variant="link">
     <a href="/">链接样式按钮</a>
   </Button>

cn 工具

className={cn(buttonVariants({ variant, size, className }))}

cn:通常是一个合并类名的工具(如 clsx 或 tailwind-merge),用于解决类名冲突。

总结

cva 是一种声明式变体样式管理方案,通过结构化配置和类型安全的方式,大幅简化了多变体组件的开发。它在设计系统、组件库中尤其有用,能够保持样式的一致性和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2394751.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通过mqtt 点灯

1 解析mqtt 传过来的json 用cjson 解析。 2 类似mvc的结构&#xff0c;调用具体的动作函数 定义设备处理结构体&#xff1a;使用结构体数组映射设备名称与处理函数&#xff0c;实现可扩展的指令分发分离设备逻辑&#xff1a;为每个设备&#xff08;如 LED、Motor&#xff0…

大数据-273 Spark MLib - 基础介绍 机器学习算法 决策树 分类原则 分类原理 基尼系数 熵

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大模型篇章已经开始&#xff01; 目前已经更新到了第 22 篇&#xff1a;大语言模型 22 - MCP 自动操作 FigmaCursor 自动设计原型 Java篇开…

基于 Spring Boot + Vue 的墙绘产品展示交易平台设计与实现【含源码+文档】

项目简介 本系统是一个基于 Spring Boot Vue 技术栈开发的墙绘产品展示交易平台&#xff0c;旨在提供一个高效、便捷的在线商城平台&#xff0c;方便用户浏览、选购墙绘产品&#xff0c;并提供管理员进行商品管理、订单管理等功能。系统采用了前后端分离的架构&#xff0c;前…

【机器学习】支持向量机

文章目录 一、支持向量机简述1.概念2.基本概念3.算法介绍4.线性可分5.算法流程 二、实验1.代码介绍2.模型流程3.实验结果4.实验小结 一、支持向量机简述 1.概念 支持向量机&#xff08;SVM&#xff09;是一类按监督学习方式对数据进行二元分类的广义线性分类器&#xff0c;其…

ONLYOFFICE深度解锁系列.4-OnlyOffice客户端原理-真的不支持多端同步

最近很多客户多要求直接部署onlyoffice服务端,还问能否和onlyoffice的客户端进行文件同步,当时真是一脸懵,还有的是老客户,已经安装了onlyoffice协作空间的,也在问如何配置客户端和协作空间的对接。由于问的人太多了,这里统一回复,先说结论,再说原理: 1.onlyoffice document s…

LLMTIME: 不用微调!如何用大模型玩转时间序列预测?

今天是端午节&#xff0c;端午安康&#xff01;值此传统佳节之际&#xff0c;我想和大家分享一篇关于基于大语言模型的时序预测算法——LLMTIME。随着人工智能技术的飞速发展&#xff0c;利用大型预训练语言模型&#xff08;LLM&#xff09;进行时间序列预测成为一个新兴且极具…

2.从0开始搭建vue项目(node.js,vue3,Ts,ES6)

从“0到跑起来一个 Vue 项目”&#xff0c;重点是各个工具之间的关联关系、职责边界和技术演化脉络。 从你写代码 → 到代码能跑起来 → 再到代码可以部署上线&#xff0c;每一步都有不同的工具参与。 &#x1f63a;&#x1f63a;1. 安装 Node.js —— 万事的根基 Node.js 是…

【pycharm】如何连接远程仓库进行版本管理(应用版本)

软件&#xff1a;Pycharm OS&#xff1a;Windows 一、Git基础设置 这里略过Git安装&#xff0c;需要可以参考&#xff1a;windows安装git&#xff08;全网最详细&#xff0c;保姆教程&#xff09;-CSDN博客 1. 配置Git 打开GitBash。分次输入下列命令。 git config --…

linux 1.0.7

用户和权限的含义与作用 linux中的用户和文件 用户的权限是非常重要的 而且有些程序需要使用管理员身份去执行 这些都是非常重要的 不可能让所有的人拥有所有的权限 这样的工具可以避免非法的手段来修改计算机中的数据 linux之所以安全还是权限管理做的很棒 每个登录的用户都有…

IEEE P370:用于高达 50 GHz 互连的夹具设计和数据质量公制标准

大多数高频仪器&#xff0c;如矢量网络分析仪 &#xff08;VNA&#xff09; 和时域反射仪 &#xff08;TDR&#xff09;&#xff0c;都可以在同轴接口的末端进行非常好的测量。然而&#xff0c;复杂系统中使用的互连很少具有同轴接口。用于表征这些设备的夹具的设计和实施会对测…

Denoising Autoencoders 视频截图 DAEs简单实现 kaggle 去噪编码器

https://www.bilibili.com/video/BV1syzrYaEtw Denoising Autoencoders (DAEs) 是一种无监督学习模型&#xff0c;属于自动编码器&#xff08;Autoencoder&#xff09;的一种扩展形式。它们的目标是通过训练神经网络来学习数据的鲁棒表示&#xff08;robust representation&a…

GoogLeNet网络模型

GoogLeNet网络模型 诞生背景 在2014年的ImageNet图像识别挑战赛中&#xff0c;一个GoogLeNet的网络架构大放异彩&#xff0c;与VGG不同的是&#xff0c;VGG用的是3*3的卷积&#xff0c;而GoogLeNet从1*1到7*7的卷积核都用&#xff0c;也就是使用不同大小的卷积核组合。 网络…

仿真科普|弥合市场需求断层,高性能仿真,“性能”与“安全”如何兼得?

2025年3月&#xff0c;塔塔科技&#xff08;Tata Technologies&#xff09;确认曾在去年遭受勒索软件组织“猎手国际”&#xff08;Hunters International&#xff09;的攻击&#xff0c;1.4TB工程数据被窃取&#xff0c;涉及航空发动机热障涂层工艺参数等超过 73 万份文件。 X…

Maven---配置本地仓库

目录 5. 5.1在Maven路径下新建文件夹用于本地仓库存储 5.2 复制本地仓库路径 5.3 找到配置文件路径&#xff0c;使用VSCode方式打开 5.4 新增一行代码 5.5 复制本地仓库路径&#xff0c;设置存储路径 5.1在Maven路径下新建文件夹用于本地仓库存储 5.2 复制本地仓库路径 5…

【C++ 】智能指针:内存管理的 “自动导航仪”

目录 一、引入 二、智能指针的两大特性&#xff1a; 1、RAII 特点&#xff1a; 好处&#xff1a; 2、行为像指针 三、智能指针起初的缺陷&#xff1a;拷贝问题 四、几种智能指针的介绍。 1、C98出现的智能指针——auto_ptr auto_ptr解决上述拷贝构造的问题&#xff1a…

设备制造行业项目管理难点解析,如何有效解决?

在设备制造行业&#xff0c;项目管理是企业运营的核心环节&#xff0c;直接影响项目交付效率、成本控制和盈利能力。然而&#xff0c;由于行业特性复杂、项目周期长、涉及部门多&#xff0c;企业在实际操作中常常面临诸多管理痛点。金众诚工程项目管理系统&#xff0c;依托金蝶…

浅谈 PAM-2 到 PAM-4 的信令技术演变

通信信令技术演进&#xff1a;从 PAM-2 到 PAM-4 在当今数字化高速发展的时代&#xff0c;数据传输需求呈爆炸式增长&#xff0c;行业对通信带宽的要求愈发严苛。为顺应这一趋势&#xff0c;通信信令技术不断革新&#xff0c;曾经占据主导地位的不归零&#xff08;NRZ&#xff…

Protos-SIP:经典 SIP 协议模糊测试工具!全参数详细教程!Kali Linux教程!

简介 该测试套件的目的是评估会话发起协议 (SIP) 实现的实现级别安全性和稳健性。 Protos-SIP 是一款专为 SIP 协议模糊测试&#xff08;Fuzzing&#xff09;设计的工具&#xff0c;最初由 OUSPG&#xff08;Oulu University Secure Programming Group&#xff09;开发&#…

复数三角不等式简介及 MATLAB 演示

复数三角不等式简介及 MATLAB 演示 1. 复数三角不等式简介 复数三角不等式&#xff08;Complex Triangle Inequality&#xff09;是复数的一种重要性质&#xff0c;它类似于普通的三角不等式&#xff0c;但适用于复数空间。具体来说&#xff0c;复数三角不等式可以描述复数之…

【Doris基础】Apache Doris 基本架构深度解析:从存储到查询的完整技术演进

目录 1 引言 2 Doris 架构全景图 2 核心组件技术解析 2.1 Frontend 层&#xff08;FE&#xff09; 2.2 Backend 层&#xff08;BE&#xff09; 3 数据存储与复制机制 3.1 存储架构演进 3.2 副本复制策略 4 查询处理全流程解析 4.1 查询生命周期 5 高可用设计 5.1 F…