@vavt/react-ui
v1.4.4
Published
A modern React component library
Readme
@vavt/react-ui
面向 React 18/19 的 TypeScript 组件库,提供 ESM、CommonJS、NodeNext 兼容声明文件以及全量/按组件 CSS 入口。
安装
npm install @vavt/react-ui使用
import { VlButton, VlCard } from '@vavt/react-ui';
import '@vavt/react-ui/styles.css';
export default function Example() {
return (
<VlCard>
<VlButton status="primary">开始使用</VlButton>
</VlCard>
);
}组件子路径和单组件样式也可以直接引用:
import { VlButton } from '@vavt/react-ui/components/Button';
import '@vavt/react-ui/base.css';
import '@vavt/react-ui/components/Button/style.css';全量样式入口 styles.css 已包含基础主题与所有组件样式,因此不要再同时引入 base.css 或单组件 CSS。
Next.js SSR / App Router
发布后的 ESM 根入口和组件子路径都声明为 Client Component。Server Component 可以导入组件并把它直接渲染进 JSX,继续获得服务端预渲染;但不能读取组件上的静态属性(见下一节)。若项目还通过源码别名或旧缓存消费,也可以用一个显式 'use client' wrapper 固定边界:
// components/ui.ts
'use client';
export { VlButton, VlModal, VlSelect } from '@vavt/react-ui';全局样式放在 app/layout.tsx 或其他全局入口中:
import '@vavt/react-ui/styles.css';Dropdown、Tooltip 等可由受控状态打开的浮层会在 hydration 首轮保持结构一致,并在客户端挂载后迁移到 document.body;Modal、Drawer 和 MessageBox 的 Portal 内容仍属于客户端增强内容。命令式 VlMessageBox.alert/confirm 只可在浏览器事件或客户端组件中调用;服务端导入 @vavt/react-ui/register 不会再修改 Node 进程级 globalThis,如需注册请显式调用 registerGlobalComponents(target)。
复合组件的静态属性不能跨 Server Component 边界
VlForm.Item、VlMessageBox.alert、VlMessageBox.confirm 是挂在组件函数上的静态属性。Server Component 从 'use client' 模块导入拿到的是打包器生成的 client reference 代理,它只应答 $$typeof、name 等少数键,点号访问任何其他属性都会在服务端渲染时抛错:
Cannot access VlForm.Item on the server. You cannot dot into a client module
from a server component. You can only pass the imported name through.TypeScript 拦不住这类错误:'use client' 是打包器层面的模块指令,类型系统里没有对应表示,声明文件只有一份、两侧解析结果相同,所以 VlForm.Item 在 Server Component 里同样能通过编译,只在运行时崩。
绝大多数情况下正确的修法是给渲染表单的文件加上 'use client'——onFinish、onChange 这类函数 prop 本来也跨不过序列化边界,可用的表单始终要在客户端文件里:
'use client';
import { VlForm, VlInput } from '@vavt/react-ui';
export default function ProfileForm() {
return (
<VlForm onFinish={save}>
<VlForm.Item name="name" label="姓名">
<VlInput />
</VlForm.Item>
</VlForm>
);
}如果确实要在 Server Component 里拼装静态结构,改用独立导出的 VlFormItem,不要点进 VlForm:
// app/page.tsx —— 无需 'use client'
import { VlForm, VlFormItem, VlInput } from '@vavt/react-ui';
export default function Page() {
return (
<VlForm>
<VlFormItem name="name" label="姓名">
<VlInput />
</VlFormItem>
</VlForm>
);
}VlMessageBox.alert/confirm 没有对应的独立导出——它们是命令式 API,只能在浏览器事件或客户端组件中调用。
自动按需导入
Vite 项目可安装独立的构建插件:
npm install -D @vavt/component-resolver// vite.config.ts
import react from '@vitejs/plugin-react';
import Components from '@vavt/component-resolver';
export default {
plugins: [react(), Components()]
};配置后可以继续使用根入口命名导入:
import { VlButton, VlCard } from '@vavt/react-ui';构建时会转换为 Button、Card 的组件子路径,并注入各自的样式入口 components/Button/style,不会加载其他组件样式。此时不要再手动导入全量 styles.css。
样式入口负责基础样式和跨组件样式依赖,因此不需要另外导入 base.css。例如 Table 内部会渲染 Scrollbar 与 Tooltip,只引用 Table 就会自动带上它们的样式;同页再单独使用 Tooltip 时,打包器按模块地址去重,不会产生重复规则。
插件也支持直接使用未导入的 <VlButton />;该模式需要在 tsconfig.json 的原有 types 中追加 @vavt/react-ui/global。@vavt/component-resolver 是消费端可选工具,不是本包的依赖。
受控 API 迁移
当前版本统一使用 React 语义的受控属性;这是破坏性变更,旧的 Vue 风格模型属性已移除。
| 组件 | 受控属性 | 非受控初始属性 |
| -------------------------------------------------- | --------- | ---------------- |
| Input、Textarea、NumberInput、Select、Slider、Tabs | value | defaultValue |
| Checkbox、Switch | checked | defaultChecked |
| Modal、MessageBox、Drawer、Dropdown、Tooltip | open | defaultOpen |
Checkbox 数组选择使用 VlCheckboxGroup,其 value/defaultValue 为 CheckboxValue[];Checkbox 的 onChange 返回 (value, checked)。Radio 使用 VlRadioGroup 管理单个 RadioValue,Radio 和 Switch 的事件也分别遵循各自组件的值语义。
全局注册与类型提示
在应用入口导入运行时注册和全量样式:
import '@vavt/react-ui/register';
import '@vavt/react-ui/styles.css';在 tsconfig.json 的已有 types 中追加 @vavt/react-ui/global:
{
"compilerOptions": {
"types": ["vite/client", "@vavt/react-ui/global"]
}
}现在可以直接使用全局组件,TypeScript 会同时检查组件名和 Props:
export default function App() {
return <VlButton status="primary">开始使用</VlButton>;
}如果项目没有配置 compilerOptions.types,也可以在应用的 .d.ts 文件中添加:
/// <reference types="@vavt/react-ui/global" />registerGlobalComponents() 也从包根入口导出,支持传入自定义对象;默认注册到 globalThis。全局注册会加载整个组件集合,按需场景仍建议使用组件子路径。
Peer dependencies
react ^18.2 || ^19react-dom ^18.2 || ^19
仓库开发说明见 开发手册。
