前端技术 · 文章

做了一个 Vue 3 组件库:Airo UI,轻盈如空气

市面上的 Vue 组件库要么臃肿到你只用十个组件却得背上整个宇宙,要么动效僵硬得像在看 PPT 翻页。Airo UI 是我从零搭建的 Vue 3 组件库——弹簧动画、克制配色、4px 网格、TypeScript 全量类型,30+ 组件按需引入。这篇文章讲它怎么来的、设计上做了哪些取舍、以及你如何三行代码跑起来。

image.png

为什么要造轮子

现有组件库的痛点

Element Plus、Ant Design Vue、Naive UI——都是好东西,但它们解决的是「企业级后台管理系统」的问题。当我想做一个个人项目、一个小工具、一个博客主题,这些库的视觉语言太重了。按钮带投影、表单带边框、弹窗带遮罩层——每一个组件都在喊「我很专业」,但我只想要「安静」。

另一个问题是动效。绝大多数组件库的状态切换用的是 ease-in-out 或 linear——机械、可预测、没有生命力。Checkbox 打勾是瞬间出现的,Switch 滑动是匀速的,Modal 弹出是线性放大的。这些交互没有错,但也没有任何惊喜。

我想要什么

一个足够克制的组件库:中性色打底,只用一个强调色;所有动效用弹簧曲线,让交互有「回弹感」而不是「滑动感」;间距严格走 4px 网格,不靠感觉调像素;TypeScript 覆盖到每一个 Prop 和 Emit,IDE 里写代码不用翻文档。

简单说:写给自己用的组件库,顺便开源。


设计原则

1. 弹簧缓动曲线

所有状态过渡统一使用 spring 曲线,拒绝 ease-in-out。Checkbox 打勾时有一个微小的弹跳,Switch 滑入时有轻微的过冲,Slider 拖动松手后有惯性衰减。这些细节单独看不起眼,但整体体验下来,你会觉得界面是「活的」。

实现上用的是一条 cubic-bezier:

--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

1.56 这个值让曲线在终点附近有一次过冲——视觉上就是「弹一下」。不需要 JavaScript 动画库,纯 CSS 就能跑。

2. 克制的配色

整套组件只有一个强调色,其余全是中性灰。默认强调色是 #9ebbde——一个安静的雾蓝。不想用?覆盖一行 CSS 变量就行:

:root {
  --color-accent: #34C796;
}

不需要 fork 源码,不需要配置文件,不需要 Sass 变量编译。一行搞定全局换肤。

3. 4px 网格体系

间距不靠感觉,靠系统。从 --space-1(4px)到 --space-12(48px),所有组件的 padding、margin、gap 都从这 12 个值里选。视觉上会有一种说不出的「对齐感」——这就是网格韵律。


三行代码跑起来

安装:

npm install @airo-ui/vue
# 或
pnpm add @airo-ui/vue

在入口文件注册:

import { createApp } from 'vue'
import AiroUI from '@airo-ui/vue'
import '@airo-ui/vue/dist/style.css'

const app = createApp(App)
app.use(AiroUI)
app.mount('#app')

在组件里直接用:

<template>
  <AButton variant="primary">确认</AButton>
  <ASwitch v-model="darkMode" />
  <ASlider v-model="volume" />
</template>

按需引入同样支持。ESM 模块化打包,Tree-shaking 友好——只用 Switch,就只打包 Switch,其余组件自动剔除。


组件清单

30+ 组件,五大分类:

分类

组件

表单基础

Button, Input, Textarea, Checkbox, Radio, Switch, Select, Slider, Segmented

反馈与通知

Toast, Modal, Tooltip, Drawer, Progress, Skeleton

数据展示

Tag, Card, Badge, Tabs, Avatar, Divider, Pagination

复合组件

ChatInput, Search

桌面专题

DropdownMenu, Table, Tree

每个组件都有完整的 TypeScript 类型定义——Props、Emits、Slots 全量导出,IDE 智能提示开箱即用。


无障碍与浏览器支持

WCAG 2.1 AA:所有交互组件都标注了正确的 ARIA 角色和状态。Switch 有 role="switch" 和 aria-checked,键盘可达(Tab 聚焦,Space 切换),屏幕阅读器能正确播报状态变化。

动画方面,组件会响应 prefers-reduced-motion 媒体查询——用户在系统设置里关闭动画后,所有弹簧效果自动降级为即时切换。

浏览器支持:Chrome、Firefox、Safari、Edge 最近两个主版本。


Airo UI 最初只是为了解决我自己的问题:我想要一套视觉安静、动效舒服、类型完备的 Vue 3 组件,在个人项目和小工具里用。做着做着发现东西越来越多,干脆整理成完整的组件库开源出来。

名字取自 Air——空气。用起来应该像空气一样:在那里,但你不会刻意注意到它。组件不应该抢你产品的风头,它应该安安静静地待在那里,把舞台留给你的内容。

如果你也在找一个轻量、克制、有弹性动画的 Vue 3 组件库,可以试试看。

Bug 反馈和功能建议欢迎直接在 GitHub Issues 提。觉得有帮助的话,给个 Star 就是最好的支持。

版权声明

本文内容版权归作者或相关权利人所有。转载、引用或其他使用请遵循相应授权条款,并保留本文链接。

本文链接:https://xuyi.dev/2026-05-19-avqlwc