@gulibs/vgrove-ui
Version:
VGrove UI component library built with HeroUI and React
2,317 lines (1,935 loc) • 64 kB
Markdown
# VGrove UI
> 现代化企业级 React UI 组件库 - 基于 HeroUI 构建,集成完整的认证、表单、布局和国际化解决方案
[](https://badge.fury.io/js/@gulibs%2Fvgrove-ui)
[](https://opensource.org/licenses/MIT)
[](http://www.typescriptlang.org/)
## ✨ 核心特性
### 🔐 现代化认证系统
- **标准化 Loader API**: 基于 React Router v7+ loader/action 模式
- **智能路由保护**: 多层级认证、角色和权限检查
- **自动重定向**: 智能跳转到登录页面或权限不足页面
- **中间件支持**: 可扩展的认证中间件链
### 📝 完整表单解决方案
- **基于 React Hook Form**: 高性能表单处理
- **智能表单状态**: watchNames 自动控制按钮启用状态
- **丰富的表单组件**: 15+ 个企业级表单组件
- **统一验证系统**: 实时验证和错误处理
### 🎨 企业级 UI 组件
- **基于 HeroUI**: 现代化设计语言
- **完整布局系统**: 响应式布局和页面管理
- **灵活主题系统**: 明暗主题 + 系统主题检测
- **国际化支持**: 内置多语言和本地化
### ⚡ 性能与开发体验
- **智能缓存**: 路由级别的性能优化
- **完整 TypeScript**: 类型安全和智能提示
- **调试工具**: 模块化调试配置
- **零配置**: 开箱即用的企业级功能
## 📦 安装
```bash
# npm
npm install @gulibs/vgrove-ui
# pnpm (推荐)
pnpm add @gulibs/vgrove-ui
# yarn
yarn add @gulibs/vgrove-ui
```
### 对等依赖
VGrove UI 需要以下对等依赖:
```bash
# 核心依赖
npm install react react-dom react-router-dom
# 样式依赖
npm install @heroui/react @heroui/theme framer-motion
npm install tailwindcss @tailwindcss/vite
# 表单依赖
npm install react-hook-form
# 可选依赖
npm install react-helmet-async # 用于页面 SEO 管理
```
### Tailwind CSS 配置
```javascript
// tailwind.config.js
const { heroui } = require("@heroui/react");
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}",
"./node_modules/@gulibs/vgrove-ui/dist/**/*.{js,ts,jsx,tsx}"
],
theme: {
extend: {},
},
darkMode: "class",
plugins: [heroui()]
}
```
## 🚀 快速开始
### 基础设置
```typescript
import React from 'react';
import { VGroveProvider, VGroveLayout } from '@gulibs/vgrove-ui';
// 侧边栏菜单配置
const menuItems = [
{
key: 'dashboard',
label: '仪表板',
href: '/dashboard',
icon: <DashboardIcon />
},
{
key: 'users',
label: '用户管理',
href: '/users',
icon: <UsersIcon />
}
];
function App() {
return (
<VGroveProvider
settings={{
sidebar: {
collapsed: false,
collapsible: true
},
navbar: {
height: 64
}
}}
>
<VGroveLayout
items={menuItems}
onCollapsedChange={(collapsed) => console.log('Sidebar collapsed:', collapsed)}
>
{/* 你的应用路由 */}
<Router />
</VGroveLayout>
</VGroveProvider>
);
}
export default App;
```
### 认证系统快速配置
```typescript
import {
quickSetup,
createBrowserRouter,
RouterProvider
} from '@gulibs/vgrove-ui';
// 快速配置认证系统
const { authLoader, loginAction, logoutAction } = quickSetup({
// 认证检查函数
authCheck: async () => {
const token = localStorage.getItem('authToken');
if (!token) return null;
const user = await fetchUserProfile(token);
return user;
},
// 登录 API
loginApi: async (credentials) => {
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credentials)
});
if (!response.ok) throw new Error('登录失败');
const { user, token } = await response.json();
localStorage.setItem('authToken', token);
return { user, token };
},
// 配置选项
loginPath: '/auth/login',
forbiddenPath: '/403',
publicPaths: ['/auth/*', '/public/*', '/'],
debug: process.env.NODE_ENV === 'development'
});
// 创建路由
const router = createBrowserRouter([
// 公共路由
{
path: '/auth/login',
element: <LoginPage />,
action: loginAction
},
// 需要认证的路由
{
path: '/dashboard',
element: <Dashboard />,
loader: authLoader
},
// 需要管理员角色的路由
{
path: '/admin',
element: <AdminPanel />,
loader: createRoleLoader(['admin', 'super-admin'])
},
// 需要特定权限的路由
{
path: '/users',
element: <UserManagement />,
loader: createPermissionLoader(['user.read', 'user.write'])
}
]);
function App() {
return (
<VGroveProvider>
<RouterProvider router={router} />
</VGroveProvider>
);
}
```
## 🔐 认证与路由系统
VGrove UI 提供了基于 React Router v7+ 的现代化认证和权限管理系统,支持多层级认证检查和智能路由保护。
### 核心 Loader API
#### 基础认证 Loader
```typescript
import { createAuthLoader, configureLoaders } from '@gulibs/vgrove-ui';
// 全局配置 (一次性配置)
configureLoaders({
authCheck: async () => {
const token = localStorage.getItem('token');
if (!token) return null;
return await fetchUserProfile(token);
},
loginPath: '/auth/login',
forbiddenPath: '/403',
publicPaths: ['/auth/*', '/public/*', '/404', '/403']
});
// 创建认证 Loader
const authLoader = createAuthLoader();
// 在路由中使用
{
path: '/dashboard',
element: <Dashboard />,
loader: authLoader // 需要用户登录
}
```
#### 角色检查 Loader
```typescript
import { createRoleLoader } from '@gulibs/vgrove-ui';
// 检查用户是否具有指定角色
const adminLoader = createRoleLoader(['admin', 'super-admin']);
const moderatorLoader = createRoleLoader(['moderator']);
// 使用示例
{
path: '/admin',
element: <AdminPanel />,
loader: adminLoader // 只有 admin 或 super-admin 可以访问
}
```
#### 权限检查 Loader
```typescript
import { createPermissionLoader } from '@gulibs/vgrove-ui';
// 检查用户是否具有指定权限
const userManagementLoader = createPermissionLoader([
'user.read',
'user.write'
]);
// 使用示例
{
path: '/users',
element: <UserManagement />,
loader: userManagementLoader // 需要用户读写权限
}
```
### 核心 Action API
#### 登录 Action
```typescript
import { createLoginAction } from '@gulibs/vgrove-ui';
const loginAction = createLoginAction(async (credentials) => {
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credentials)
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || '登录失败');
}
const { user, token } = await response.json();
localStorage.setItem('authToken', token);
return { user, token };
});
// 在路由中使用
{
path: '/auth/login',
element: <LoginPage />,
action: loginAction
}
```
#### 自定义 Action
```typescript
import { createAction } from '@gulibs/vgrove-ui';
const updateProfileAction = createAction({
// 表单验证
validator: async (formData) => {
const errors = [];
if (!formData.get('name')) {
errors.push({ field: 'name', message: '姓名不能为空' });
}
return errors;
},
// 数据处理
processor: async (formData, user) => {
return await updateUserProfile(user.id, {
name: formData.get('name'),
email: formData.get('email')
});
},
requireAuth: true,
successRedirect: '/profile'
});
```
## 📝 表单组件系统
VGrove UI 提供了基于 React Hook Form 的完整表单解决方案,包含 15+ 个企业级表单组件和智能表单状态管理。
### 核心表单组件
#### Form 表单容器
Form 组件是表单系统的核心,提供了统一的表单处理、验证和状态管理。
```typescript
import { Form, FormItem, Input, Button } from '@gulibs/vgrove-ui';
function UserForm() {
const handleSubmit = async (data) => {
console.log('表单数据:', data);
// 处理表单提交
};
const handleError = (errors) => {
console.log('验证错误:', errors);
};
return (
<Form
mode="onChange" // 验证模式: onChange | onBlur | onSubmit | all
watchNames={['username', 'email']} // 监听字段,控制按钮状态
onFinish={handleSubmit}
onFinishError={handleError}
footer={{
submitText: '提交',
resetText: '重置',
hiddenReset: false
}}
>
<FormItem name="username" label="用户名" required>
<Input placeholder="请输入用户名" />
</FormItem>
<FormItem name="email" label="邮箱" required>
<Input type="email" placeholder="请输入邮箱" />
</FormItem>
</Form>
);
}
```
**Form 组件特性:**
- **智能按钮状态**: `watchNames` 属性自动控制提交按钮启用 / 禁用
- **多种验证模式**: 支持实时验证和提交时验证
- **可配置页脚**: 自定义提交和重置按钮
- **完整 TypeScript 支持**: 类型安全的表单处理
#### FormItem 表单项包装器
FormItem 为表单字段提供统一的标签、验证和错误显示。
```typescript
import { FormItem, Input, Textarea, Select } from '@gulibs/vgrove-ui';
function ProfileForm() {
return (
<Form onFinish={handleSubmit}>
{/* 基础表单项 */}
<FormItem
name="name"
label="姓名"
required
help="请输入您的真实姓名"
rules={{
required: { value: true, message: '姓名必填' },
minLength: { value: 2, message: '姓名至少2个字符' }
}}
>
<Input />
</FormItem>
{/* 带工具提示的表单项 */}
<FormItem
name="bio"
label="个人简介"
tooltip={{
content: "简要介绍您的背景和经历",
placement: "top"
}}
>
<Textarea rows={4} />
</FormItem>
{/* 自定义验证状态 */}
<FormItem
name="status"
label="状态"
validateStatus="success"
>
<Select>
<option value="active">活跃</option>
<option value="inactive">非活跃</option>
</Select>
</FormItem>
</Form>
);
}
```
**FormItem 特性:**
- **灵活布局**: 支持垂直和水平布局
- **工具提示**: 内置 Tooltip 支持
- **验证状态**: 视觉化验证反馈
- **帮助文本**: 支持帮助信息显示
#### FormGroup 表单分组
用于将相关的表单字段分组显示。
```typescript
import { FormGroup, FormItem, Input } from '@gulibs/vgrove-ui';
function AddressForm() {
return (
<Form onFinish={handleSubmit}>
<FormGroup title="基本信息">
<FormItem name="firstName" label="名">
<Input />
</FormItem>
<FormItem name="lastName" label="姓">
<Input />
</FormItem>
</FormGroup>
<FormGroup title="联系信息">
<FormItem name="email" label="邮箱">
<Input type="email" />
</FormItem>
<FormItem name="phone" label="电话">
<Input type="tel" />
</FormItem>
</FormGroup>
</Form>
);
}
```
### 输入组件
#### Input 输入框
基于 HeroUI Input 的增强版本,集成了表单验证和状态管理。
```typescript
import { Form, FormItem, Input } from '@gulibs/vgrove-ui';
function InputExamples() {
return (
<Form onFinish={handleSubmit}>
{/* 基础输入框 */}
<FormItem name="username" label="用户名" required>
<Input
placeholder="请输入用户名"
startContent={<UserIcon />}
/>
</FormItem>
{/* 密码输入框 */}
<FormItem name="password" label="密码" required>
<Input
type="password"
placeholder="请输入密码"
endContent={<EyeIcon />}
/>
</FormItem>
{/* 带验证规则的输入框 */}
<FormItem
name="email"
label="邮箱"
required
rules={{
pattern: {
value: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/,
message: '请输入有效的邮箱地址'
}
}}
>
<Input
type="email"
placeholder="example@domain.com"
/>
</FormItem>
{/* 数字输入框 */}
<FormItem name="age" label="年龄">
<Input
type="number"
min={1}
max={120}
placeholder="请输入年龄"
/>
</FormItem>
</Form>
);
}
```
#### Textarea 多行文本
```typescript
import { FormItem, Textarea } from '@gulibs/vgrove-ui';
<FormItem
name="description"
label="描述"
rules={{
maxLength: { value: 500, message: '描述不能超过500字符' }
}}
>
<Textarea
rows={4}
placeholder="请输入详细描述..."
maxLength={500}
/>
</FormItem>
```
#### Autocomplete 自动完成
```typescript
import { FormItem, Autocomplete } from '@gulibs/vgrove-ui';
const suggestions = [
{ value: 'apple', label: '苹果' },
{ value: 'banana', label: '香蕉' },
{ value: 'orange', label: '橙子' }
];
<FormItem name="fruit" label="选择水果">
<Autocomplete
options={suggestions}
placeholder="输入或选择水果"
allowsCustomValue
/>
</FormItem>
```
### 选择组件
#### Select 下拉选择
```typescript
import { FormItem, Select } from '@gulibs/vgrove-ui';
<FormItem name="category" label="分类" required>
<Select placeholder="请选择分类">
<option value="tech">技术</option>
<option value="design">设计</option>
<option value="business">商业</option>
</Select>
</FormItem>
```
#### Radio 单选按钮
```typescript
import { FormItem, Radio, RadioGroup } from '@gulibs/vgrove-ui';
// 单个单选按钮
<FormItem name="agree" label="同意条款">
<Radio value="yes">我同意用户协议</Radio>
</FormItem>
// 单选按钮组
<FormItem name="gender" label="性别">
<RadioGroup orientation="horizontal">
<Radio value="male">男</Radio>
<Radio value="female">女</Radio>
<Radio value="other">其他</Radio>
</RadioGroup>
</FormItem>
```
#### Checkbox 复选框
```typescript
import { FormItem, Checkbox, CheckboxGroup } from '@gulibs/vgrove-ui';
// 单个复选框
<FormItem name="newsletter" label="订阅">
<Checkbox>订阅邮件通知</Checkbox>
</FormItem>
// 复选框组
<FormItem name="interests" label="兴趣爱好">
<CheckboxGroup>
<Checkbox value="reading">阅读</Checkbox>
<Checkbox value="travel">旅行</Checkbox>
<Checkbox value="music">音乐</Checkbox>
<Checkbox value="sports">运动</Checkbox>
</CheckboxGroup>
</FormItem>
```
### 特殊输入组件
#### Switch 开关
```typescript
import { FormItem, Switch } from '@gulibs/vgrove-ui';
<FormItem name="notifications" label="推送通知">
<Switch
defaultSelected
color="success"
startContent={<BellIcon />}
endContent={<BellSlashIcon />}
>
启用推送通知
</Switch>
</FormItem>
```
#### Slider 滑动条
```typescript
import { FormItem, Slider } from '@gulibs/vgrove-ui';
<FormItem name="volume" label="音量">
<Slider
step={10}
minValue={0}
maxValue={100}
defaultValue={50}
className="max-w-md"
/>
</FormItem>
```
#### DatePicker 日期选择器
```typescript
import { FormItem, DatePicker } from '@gulibs/vgrove-ui';
<FormItem name="birthdate" label="出生日期">
<DatePicker
label="选择日期"
className="max-w-sm"
/>
</FormItem>
<FormItem name="appointment" label="预约时间">
<DatePicker
label="选择日期时间"
showTimeSelect
timeFormat="HH:mm"
timeIntervals={15}
dateFormat="MMMM d, yyyy h:mm aa"
/>
</FormItem>
```
#### TimeInput 时间输入
```typescript
import { FormItem, TimeInput } from '@gulibs/vgrove-ui';
<FormItem name="startTime" label="开始时间">
<TimeInput
label="时间"
hourCycle={24}
/>
</FormItem>
```
### 表单验证
#### 内置验证规则
```typescript
import { Form, FormItem, Input } from '@gulibs/vgrove-ui';
function ValidationExample() {
return (
<Form onFinish={handleSubmit}>
<FormItem
name="username"
label="用户名"
required
rules={{
required: { value: true, message: '用户名必填' },
minLength: { value: 3, message: '用户名至少3个字符' },
maxLength: { value: 20, message: '用户名最多20个字符' },
pattern: {
value: /^[a-zA-Z0-9_]+$/,
message: '用户名只能包含字母、数字和下划线'
}
}}
>
<Input placeholder="请输入用户名" />
</FormItem>
<FormItem
name="password"
label="密码"
required
rules={{
required: { value: true, message: '密码必填' },
minLength: { value: 6, message: '密码至少6个字符' },
validate: {
hasNumber: (value) => /\\d/.test(value) || '密码必须包含数字',
hasLetter: (value) => /[a-zA-Z]/.test(value) || '密码必须包含字母'
}
}}
>
<Input type="password" placeholder="请输入密码" />
</FormItem>
</Form>
);
}
```
#### 自定义验证
```typescript
// 异步验证
const checkUsernameAvailability = async (username) => {
const response = await fetch(`/api/check-username/${username}`);
const { available } = await response.json();
return available || '用户名已被占用';
};
<FormItem
name="username"
label="用户名"
rules={{
validate: {
availability: checkUsernameAvailability
}
}}
>
<Input placeholder="请输入用户名" />
</FormItem>
```
### FormInstance API
VGrove UI 提供了增强的 FormInstance 接口,它扩展了 react-hook-form 的 UseFormReturn,并添加了更直观的 API 方法。
#### 接口定义
```typescript
interface FormInstance<TFieldValues> extends UseFormReturn<TFieldValues> {
// 基础方法
getFieldValue: (name: FieldPath<TFieldValues>) => any;
getFieldsValue: () => TFieldValues;
setFieldValue: (name: FieldPath<TFieldValues>, value: any) => void;
setFieldsValue: (values: Partial<TFieldValues>) => void;
resetFields: () => void;
// 验证方法
validateFields: () => Promise<boolean>;
setFieldError: (name: FieldPath<TFieldValues>, error: any) => void;
clearFieldErrors: (names?: FieldPath<TFieldValues>[]) => void;
}
```
#### useForm Hook 使用
```typescript
import { useForm } from '@gulibs/vgrove-ui';
function UserForm() {
// useForm 现在返回 FormInstance 而非 UseFormReturn
const form = useForm<{ username: string; email: string }>();
const handleTestAPI = () => {
// 新增的便捷方法
const username = form.getFieldValue('username');
const allValues = form.getFieldsValue();
form.setFieldValue('username', 'newValue');
form.setFieldsValue({ username: 'test', email: 'test@example.com' });
form.resetFields();
form.validateFields().then(isValid => {
console.log('表单验证结果:', isValid);
});
form.setFieldError('username', { type: 'manual', message: '用户名已存在' });
form.clearFieldErrors(['username']);
// 仍然可以使用所有原生 react-hook-form 方法
console.log('FormState:', form.formState);
console.log('Watch:', form.watch());
};
return (
<Form form={form} onFinish={console.log}>
<FormItem name="username" label="用户名">
<Input />
</FormItem>
<FormItem name="email" label="邮箱">
<Input type="email" />
</FormItem>
<Button onClick={handleTestAPI}>测试 API</Button>
</Form>
);
}
```
#### createFormInstance 工具函数
如果您已经有一个 UseFormReturn 实例,可以使用 `createFormInstance` 将其转换为 FormInstance:
```typescript
import { useForm as useRHFForm } from 'react-hook-form';
import { createFormInstance } from '@gulibs/vgrove-ui';
function MyComponent() {
// 使用原生 react-hook-form
const rhfForm = useRHFForm();
// 转换为 FormInstance
const form = createFormInstance(rhfForm);
// 现在可以使用增强的 API
const handleSubmit = () => {
const values = form.getFieldsValue();
console.log('表单值:', values);
};
return (
<Form form={form} onFinish={handleSubmit}>
{/* 表单内容 */}
</Form>
);
}
```
#### API 方法详解
| 方法 | 说明 | 对应的 react-hook-form 方法 |
|------|------|----------------------------|
| `getFieldValue(name)` | 获取单个字段值 | `getValues(name)` |
| `getFieldsValue()` | 获取所有字段值 | `getValues()` |
| `setFieldValue(name, value)` | 设置单个字段值 | `setValue(name, value)` |
| `setFieldsValue(values)` | 批量设置字段值 | 多次调用 `setValue` |
| `resetFields()` | 重置表单 | `reset()` |
| `validateFields()` | 验证表单并返回结果 | `trigger()` |
| `setFieldError(name, error)` | 设置字段错误 | `setError(name, error)` |
| `clearFieldErrors(names?)` | 清除字段错误 | `clearErrors(names)` |
#### 与原生 react-hook-form 的兼容性
FormInstance 完全兼容 react-hook-form 的 UseFormReturn 接口,您可以无缝使用所有原生方法:
```typescript
function CompatibilityExample() {
const form = useForm();
const testCompatibility = () => {
// VGrove UI 增强方法
form.setFieldsValue({ name: 'test' });
// 原生 react-hook-form 方法
form.register('username');
form.handleSubmit(console.log);
form.formState.errors;
form.control;
// 两者可以混合使用
const isValid = await form.validateFields(); // VGrove UI 方法
if (!isValid) {
form.setFocus('username'); // 原生方法
}
};
return <Button onClick={testCompatibility}>测试兼容性</Button>;
}
```
### 表单 Hooks
#### useWatch 监听字段变化
```typescript
import { useWatch, useFieldValue, useFieldsWatcher } from '@gulibs/vgrove-ui';
function FormWithHooks() {
// 监听单个字段
const username = useFieldValue('username');
// 监听多个字段
const [firstName, lastName] = useWatch(['firstName', 'lastName']);
// 监听字段并获取状态
const { values, allFilled, anyFilled } = useFieldsWatcher(['name', 'email']);
return (
<Form>
<FormItem name="username" label="用户名">
<Input />
</FormItem>
<FormItem name="firstName" label="名">
<Input />
</FormItem>
<FormItem name="lastName" label="姓">
<Input />
</FormItem>
{/* 实时显示 */}
<div className="p-4 bg-gray-50 rounded">
<p>用户名: {username}</p>
<p>全名: {firstName && lastName ? `${firstName} ${lastName}` : '未完整'}</p>
<p>表单状态: {allFilled ? '完成' : anyFilled ? '部分完成' : '未开始'}</p>
</div>
</Form>
);
}
```
#### useFormContext 获取表单上下文
useFormContext 现在返回 FormInstance 而非 UseFormReturn,提供了更便捷的 API:
```typescript
import { useFormContext } from '@gulibs/vgrove-ui';
function CustomFormComponent() {
// 获取 FormInstance,包含所有增强方法
const form = useFormContext();
const handleReset = () => {
// 使用新的便捷方法
form.setFieldsValue({ username: '', email: '' });
// 或者使用原生方法
form.setValue('username', '');
form.setValue('email', '');
};
const handleQuickFill = () => {
// 批量设置字段值
form.setFieldsValue({
username: 'testuser',
email: 'test@example.com'
});
};
const handleValidate = async () => {
// 使用增强的验证方法
const isValid = await form.validateFields();
if (!isValid) {
console.log('表单验证失败');
}
};
return (
<div className="space-y-4">
<div className="flex space-x-2">
<Button onClick={handleReset} disabled={form.formState.isSubmitting}>
重置表单
</Button>
<Button onClick={handleQuickFill} variant="flat">
快速填充
</Button>
<Button onClick={handleValidate} variant="flat">
验证表单
</Button>
</div>
{Object.keys(form.formState.errors).length > 0 && (
<div className="text-red-500">
表单有 {Object.keys(form.formState.errors).length} 个错误
</div>
)}
{/* 显示当前表单值 */}
<div className="p-4 bg-gray-50 rounded">
<h4 className="font-semibold mb-2">当前表单值:</h4>
<pre className="text-sm">
{JSON.stringify(form.getFieldsValue(), null, 2)}
</pre>
</div>
</div>
);
}
```
#### 在表单外部使用 FormInstance
您可以通过全局注册的方式在表单外部访问 FormInstance:
```typescript
import { useForm, registerFormInstance, getFormInstance } from '@gulibs/vgrove-ui';
function FormComponent() {
const form = useForm({
registerAsGlobal: true,
globalKey: 'userForm' // 可选,不提供则作为默认实例
});
return (
<Form form={form}>
<FormItem name="username" label="用户名">
<Input />
</FormItem>
</Form>
);
}
function ExternalController() {
const handleFillForm = () => {
// 获取全局注册的表单实例
const form = getFormInstance('userForm');
if (form) {
form.setFieldValue('username', '外部设置的值');
}
};
const handleValidateForm = async () => {
const form = getFormInstance('userForm');
if (form) {
const isValid = await form.validateFields();
console.log('外部验证结果:', isValid);
}
};
return (
<div className="space-x-2">
<Button onClick={handleFillForm}>填充表单</Button>
<Button onClick={handleValidateForm}>验证表单</Button>
</div>
);
}
```
### 完整表单示例
以下示例展示了如何使用新的 FormInstance API 构建完整的表单:
```typescript
import React from 'react';
import {
Form,
FormItem,
FormGroup,
Input,
Select,
Textarea,
Checkbox,
Switch,
DatePicker,
useForm,
Button
} from '@gulibs/vgrove-ui';
interface UserFormData {
firstName: string;
lastName: string;
email: string;
birthdate?: string;
position: string;
bio?: string;
newsletter: boolean;
notifications: boolean;
}
function CompleteUserForm() {
// 使用增强的 useForm,返回 FormInstance
const form = useForm<UserFormData>({
mode: 'onChange',
defaultValues: {
newsletter: false,
notifications: true
}
});
const handleSubmit = async (data: UserFormData) => {
try {
console.log('提交数据:', data);
// 使用 FormInstance 方法验证
const isValid = await form.validateFields();
if (!isValid) {
console.log('表单验证失败');
return;
}
// 调用 API 保存数据
await saveUserProfile(data);
// 成功后可以重置表单
form.resetFields();
} catch (error) {
console.error('保存失败:', error);
// 设置错误信息
form.setFieldError('email', {
type: 'manual',
message: '保存失败,请检查邮箱是否已被使用'
});
}
};
const handleError = (errors: any) => {
console.log('验证错误:', errors);
};
// 快速填充示例数据
const handleQuickFill = () => {
form.setFieldsValue({
firstName: '张',
lastName: '三',
email: 'zhangsan@example.com',
position: 'developer',
bio: '这是一个测试用户的个人简介。'
});
};
// 获取当前表单值
const handleGetValues = () => {
const allValues = form.getFieldsValue();
const firstName = form.getFieldValue('firstName');
console.log('所有值:', allValues);
console.log('名字:', firstName);
};
return (
<div className="max-w-2xl mx-auto p-6 space-y-6">
{/* 表单操作按钮 */}
<div className="flex space-x-2 mb-4">
<Button onClick={handleQuickFill} variant="flat">
快速填充
</Button>
<Button onClick={handleGetValues} variant="flat">
获取表单值
</Button>
<Button
onClick={() => form.resetFields()}
variant="flat"
color="warning"
>
重置表单
</Button>
</div>
<Form
form={form}
watchNames={['firstName', 'lastName', 'email']}
onFinish={handleSubmit}
onFinishError={handleError}
footer={{
submitText: '保存用户信息',
resetText: '重置表单'
}}
>
<FormGroup title="基本信息">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormItem name="firstName" label="名" required>
<Input placeholder="请输入名" />
</FormItem>
<FormItem name="lastName" label="姓" required>
<Input placeholder="请输入姓" />
</FormItem>
</div>
<FormItem
name="email"
label="邮箱"
required
rules={{
pattern: {
value: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/,
message: '请输入有效的邮箱地址'
}
}}
>
<Input type="email" placeholder="example@domain.com" />
</FormItem>
<FormItem name="birthdate" label="出生日期">
<DatePicker className="max-w-sm" />
</FormItem>
</FormGroup>
<FormGroup title="工作信息">
<FormItem name="position" label="职位">
<Select placeholder="请选择职位">
<option value="developer">开发工程师</option>
<option value="designer">设计师</option>
<option value="pm">产品经理</option>
<option value="other">其他</option>
</Select>
</FormItem>
<FormItem name="bio" label="个人简介">
<Textarea
rows={4}
placeholder="请简要介绍您的背景和经历..."
maxLength={500}
/>
</FormItem>
</FormGroup>
<FormGroup title="设置">
<FormItem name="newsletter" label="邮件订阅">
<Checkbox>订阅产品更新和新闻</Checkbox>
</FormItem>
<FormItem name="notifications" label="推送通知">
<Switch defaultSelected>
启用桌面通知
</Switch>
</FormItem>
</FormGroup>
</Form>
);
}
export default CompleteUserForm;
```
## 🏗️ 布局和 UI 组件系统
VGrove UI 提供了完整的布局系统和基础 UI 组件,支持响应式设计和灵活配置。
### 核心布局组件
#### VGroveLayout 主布局容器
VGroveLayout 是应用的主要布局容器,提供了完整的页面结构管理。
```typescript
import { VGroveLayout } from '@gulibs/vgrove-ui';
// 侧边栏菜单配置
const menuItems = [
{
key: 'dashboard',
label: '仪表板',
href: '/dashboard',
icon: <DashboardIcon />,
badge: { content: '新', color: 'success' }
},
{
key: 'users',
label: '用户管理',
icon: <UsersIcon />,
children: [
{ key: 'user-list', label: '用户列表', href: '/users' },
{ key: 'user-roles', label: '角色管理', href: '/users/roles' },
{ key: 'user-permissions', label: '权限管理', href: '/users/permissions' }
]
},
{
key: 'settings',
label: '系统设置',
href: '/settings',
icon: <SettingsIcon />,
requiredRoles: ['admin'] // 需要管理员角色
}
];
function App() {
return (
<VGroveProvider>
<VGroveLayout
items={menuItems}
onCollapsedChange={(collapsed) => {
console.log('侧边栏折叠状态:', collapsed);
}}
navbarProps={{
brandProps: {
name: "我的应用",
logo: <AppLogo />
},
userMenuProps: {
user: currentUser,
onLogout: handleLogout
}
}}
sidebarProps={{
defaultCollapsed: false,
collapsible: true
}}
footerProps={{
copyright: "© 2024 我的公司",
links: [
{ label: '隐私政策', href: '/privacy' },
{ label: '服务条款', href: '/terms' }
]
}}
classNames={{
layout: "min-h-screen",
wrapper: "max-w-full",
content: "p-6"
}}
>
{/* 应用路由内容 */}
<RouterProvider router={router} />
</VGroveLayout>
</VGroveProvider>
);
}
```
**VGroveLayout 特性:**
- **响应式布局**: 自动适配不同屏幕尺寸
- **可配置组件**: 灵活配置导航栏、侧边栏、页脚
- **实例管理**: 防止多实例冲突的安全机制
- **权限集成**: 支持基于角色的菜单显示
#### VGroveNavbar 导航栏
```typescript
import { VGroveNavbar } from '@gulibs/vgrove-ui';
function CustomNavbar() {
return (
<VGroveNavbar
brandProps={{
name: "VGrove UI",
logo: <Logo />,
onClick: () => navigate('/')
}}
searchProps={{
placeholder: "搜索功能、用户、内容...",
onSearch: (query) => handleSearch(query)
}}
userMenuProps={{
user: {
id: '1',
name: '张三',
email: 'zhangsan@example.com',
avatar: '/avatars/zhangsan.jpg'
},
menuItems: [
{ key: 'profile', label: '个人资料', href: '/profile' },
{ key: 'settings', label: '账号设置', href: '/settings' },
{ type: 'divider' },
{ key: 'logout', label: '退出登录', color: 'danger', onAction: handleLogout }
]
}}
notificationProps={{
items: notifications,
onMarkAsRead: handleMarkAsRead,
onClearAll: handleClearAll
}}
themeSwitch={{
variant: 'circle',
showLabel: false
}}
classNames={{
base: "bg-background/70 backdrop-blur-lg",
wrapper: "px-6",
brand: "font-bold"
}}
/>
);
}
```
#### VGroveSidebar 侧边栏
```typescript
import { VGroveSidebar } from '@gulibs/vgrove-ui';
const sidebarMenus = [
{
key: 'main',
type: 'group',
title: '主要功能',
items: [
{
key: 'dashboard',
label: '仪表板',
href: '/dashboard',
icon: <DashboardIcon />,
shortcut: 'Cmd+D'
},
{
key: 'analytics',
label: '数据分析',
href: '/analytics',
icon: <ChartIcon />,
badge: { content: 'Beta', color: 'warning' }
}
]
},
{
key: 'management',
type: 'group',
title: '管理功能',
items: [
{
key: 'users',
label: '用户管理',
icon: <UsersIcon />,
children: [
{ key: 'user-list', label: '用户列表', href: '/users' },
{ key: 'user-groups', label: '用户组', href: '/users/groups' }
]
}
]
}
];
function CustomSidebar() {
return (
<VGroveSidebar
menuItems={sidebarMenus}
defaultCollapsed={false}
collapsible={true}
onCollapsedChange={(collapsed) => {
localStorage.setItem('sidebarCollapsed', collapsed.toString());
}}
headerContent={
<div className="px-3 py-2">
<Brand name="VGrove UI" logo={<Logo />} />
</div>
}
footerContent={
<div className="px-3 py-2 text-xs text-default-400">
版本 v1.0.0
</div>
}
classNames={{
base: "border-r border-divider",
header: "border-b border-divider",
content: "py-2",
footer: "border-t border-divider"
}}
/>
);
}
```
#### VGroveFooter 页脚
```typescript
import { VGroveFooter, DefaultFooter } from '@gulibs/vgrove-ui';
// 使用默认页脚
function SimpleFooter() {
return (
<DefaultFooter
copyright="© 2024 我的公司"
links={[
{ label: '关于我们', href: '/about' },
{ label: '联系我们', href: '/contact' },
{ label: '隐私政策', href: '/privacy' }
]}
/>
);
}
// 自定义页脚
function CustomFooter() {
return (
<VGroveFooter className="bg-content1 border-t border-divider">
<div className="max-w-7xl mx-auto px-6 py-8">
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
<div>
<h3 className="font-semibold mb-3">产品</h3>
<ul className="space-y-2 text-sm text-default-600">
<li><a href="/features">功能特性</a></li>
<li><a href="/pricing">价格方案</a></li>
<li><a href="/api">API 文档</a></li>
</ul>
</div>
<div>
<h3 className="font-semibold mb-3">支持</h3>
<ul className="space-y-2 text-sm text-default-600">
<li><a href="/docs">文档中心</a></li>
<li><a href="/support">技术支持</a></li>
<li><a href="/community">社区论坛</a></li>
</ul>
</div>
<div>
<h3 className="font-semibold mb-3">公司</h3>
<ul className="space-y-2 text-sm text-default-600">
<li><a href="/about">关于我们</a></li>
<li><a href="/careers">招聘信息</a></li>
<li><a href="/contact">联系我们</a></li>
</ul>
</div>
<div>
<h3 className="font-semibold mb-3">关注我们</h3>
<div className="flex space-x-3">
<a href="#" className="text-default-400 hover:text-default-600">
<TwitterIcon size={20} />
</a>
<a href="#" className="text-default-400 hover:text-default-600">
<GithubIcon size={20} />
</a>
<a href="#" className="text-default-400 hover:text-default-600">
<DiscordIcon size={20} />
</a>
</div>
</div>
</div>
<div className="border-t border-divider mt-8 pt-6 text-center text-sm text-default-600">
© 2024 我的公司. 保留所有权利.
</div>
</div>
</VGroveFooter>
);
}
```
### 页面组件
#### PageContainer 页面容器
PageContainer 为页面内容提供统一的容器和间距管理。
```typescript
import { PageContainer, PageTitle } from '@gulibs/vgrove-ui';
function DashboardPage() {
return (
<PageContainer
title="数据仪表板"
subtitle="查看您的业务数据和分析报告"
breadcrumbs={[
{ label: '首页', href: '/' },
{ label: '仪表板' }
]}
actions={[
<Button key="export" variant="flat" startContent={<ExportIcon />}>
导出数据
</Button>,
<Button key="settings" variant="flat" startContent={<SettingsIcon />}>
设置
</Button>
]}
classNames={{
title: "text-3xl font-bold",
main: "mt-6 space-y-6"
}}
>
{/* 页面内容 */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<StatCard title="总用户数" value="1,234" trend="+12%" />
<StatCard title="活跃用户" value="856" trend="+8%" />
<StatCard title="新增用户" value="42" trend="+15%" />
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<ChartCard title="用户增长趋势" />
<ChartCard title="活跃度分析" />
</div>
</PageContainer>
);
}
```
#### PageTitle 页面标题
PageTitle 组件提供 SEO 友好的页面标题管理和面包屑导航。
```typescript
import { PageTitle } from '@gulibs/vgrove-ui';
function UserProfilePage() {
return (
<>
<PageTitle
title="用户资料"
subtitle="管理您的个人信息和偏好设置"
breadcrumbs={[
{ label: '首页', href: '/' },
{ label: '账户', href: '/account' },
{ label: '用户资料' }
]}
meta={{
description: '用户个人资料管理页面',
keywords: ['用户', '资料', '设置', '个人信息']
}}
/>
{/* 页面内容 */}
<div className="max-w-4xl mx-auto p-6">
{/* ... */}
</div>
</>
);
}
```
### 基础 UI 组件
#### Brand 品牌组件
Brand 组件用于显示应用品牌信息,支持 Logo 和名称的灵活配置。
```typescript
import { Brand } from '@gulibs/vgrove-ui';
function AppBrand() {
return (
<Brand
name="VGrove UI"
logo={<Logo className="w-8 h-8" />}
collapsed={sidebarCollapsed}
onClick={() => navigate('/')}
classNames={{
base: "cursor-pointer hover:opacity-80 transition-opacity",
logo: "mr-3",
nameWrapper: "overflow-hidden",
name: "font-bold text-lg truncate"
}}
/>
);
}
// 仅显示 Logo 的紧凑模式
function CompactBrand() {
return (
<Brand
logo={<Logo className="w-10 h-10" />}
collapsed={true}
onClick={() => navigate('/')}
/>
);
}
```
#### ThemeSwitch 主题切换器
ThemeSwitch 提供了多种主题切换界面,支持明暗主题和系统主题。
```typescript
import { ThemeSwitch } from '@gulibs/vgrove-ui';
function ThemeControls() {
return (
<div className="flex items-center space-x-4">
{/* 开关样式 */}
<ThemeSwitch
variant="switch"
size="md"
showLabel={true}
/>
{/* 下拉菜单样式 */}
<ThemeSwitch
variant="dropdown"
enableSystem={true}
onThemeChange={(theme, resolvedTheme) => {
console.log('主题变更:', theme, '解析主题:', resolvedTheme);
}}
/>
{/* 圆形按钮样式 */}
<ThemeSwitch
variant="circle"
size="lg"
/>
{/* 按钮组样式 */}
<ThemeSwitch
variant="buttons"
enableSystem={true}
showLabel={true}
/>
</div>
);
}
```
#### Collapse 折叠组件
Collapse 组件提供了折叠 / 展开功能,常用于侧边栏控制。
```typescript
import { Collapse } from '@gulibs/vgrove-ui';
function SidebarToggle() {
const [collapsed, setCollapsed] = useState(false);
return (
<Collapse
collapsed={collapsed}
onCollapsedChange={setCollapsed}
className="p-2 hover:bg-default-100 rounded-lg transition-colors"
icon={<MenuIcon />}
tooltip={{
content: collapsed ? '展开侧边栏' : '折叠侧边栏',
placement: 'right'
}}
/>
);
}
```
### 高级组件
#### Listbox 列表选择器
Listbox 组件提供了强大的列表选择功能,支持键盘导航和多选。
```typescript
import { Listbox, ListboxItem, ListboxSection } from '@gulibs/vgrove-ui';
function UserListbox() {
const [selected, setSelected] = useState(new Set(['user1']));
return (
<Listbox
aria-label="用户选择"
variant="flat"
disallowEmptySelection
selectionMode="multiple"
selectedKeys={selected}
onSelectionChange={setSelected}
className="max-w-xs"
>
<ListboxSection title="管理员">
<ListboxItem
key="admin1"
startContent={<Avatar size="sm" src="/avatars/admin1.jpg" />}
description="系统管理员"
>
张管理员
</ListboxItem>
<ListboxItem
key="admin2"
startContent={<Avatar size="sm" src="/avatars/admin2.jpg" />}
description="内容管理员"
>
李管理员
</ListboxItem>
</ListboxSection>
<ListboxSection title="普通用户">
<ListboxItem
key="user1"
startContent={<Avatar size="sm" src="/avatars/user1.jpg" />}
description="活跃用户"
>
王用户
</ListboxItem>
<ListboxItem
key="user2"
startContent={<Avatar size="sm" src="/avatars/user2.jpg" />}
description="新用户"
>
刘用户
</ListboxItem>
</ListboxSection>
</Listbox>
);
}
```
### 响应式布局配置
#### 布局设置
```typescript
import { VGroveProvider } from '@gulibs/vgrove-ui';
function App() {
const layoutSettings = {
// 侧边栏配置
sidebar: {
width: 280, // 展开宽度
collapsedWidth: 72, // 折叠宽度
collapsible: true, // 是否可折叠
collapsed: false, // 默认折叠状态
breakpoint: 'lg' // 响应式断点
},
// 导航栏配置
navbar: {
height: 64, // 导航栏高度
fixed: true, // 是否固定
transparent: false, // 是否透明
blur: true // 是否启用模糊效果
},
// 页脚配置
footer: {
height: 60, // 页脚高度
fixed: false, // 是否固定
show: true // 是否显示
},
// 内容区域配置
content: {
padding: 24, // 内容区域内边距
maxWidth: '100%', // 最大宽度
centered: false // 是否居中
}
};
return (
<VGroveProvider settings={layoutSettings}>
<VGroveLayout items={menuItems}>
<Router />
</VGroveLayout>
</VGroveProvider>
);
}
```
### 样式定制
#### CSS 变量定制
```css
/* 自定义 CSS 变量 */
:root {
/* 布局尺寸 */
--vgrove-sidebar-width: 280px;
--vgrove-sidebar-collapsed-width: 72px;
--vgrove-navbar-height: 64px;
--vgrove-footer-height: 60px;
/* 间距 */
--vgrove-content-padding: 24px;
--vgrove-page-max-width: 1200px;
/* 过渡动画 */
--vgrove-transition-duration: 200ms;
--vgrove-transition-timing: ease-in-out;
/* 阴影 */
--vgrove-sidebar-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
--vgrove-navbar-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* 暗色主题定制 */
.dark {
--vgrove-sidebar-shadow: 2px 0 8px rgba(0, 0, 0, 0.3);
--vgrove-navbar-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
```
#### Tailwind CSS 配置扩展
```javascript
// tailwind.config.js
module.exports = {
// ... 其他配置
theme: {
extend: {
spacing: {
'sidebar': 'var(--vgrove-sidebar-width)',
'sidebar-collapsed': 'var(--vgrove-sidebar-collapsed-width)',
'navbar': 'var(--vgrove-navbar-height)',
'footer': 'var(--vgrove-footer-height)'
},
transitionDuration: {
'vgrove': 'var(--vgrove-transition-duration)'
},
boxShadow: {
'sidebar': 'var(--vgrove-sidebar-shadow)',
'navbar': 'var(--vgrove-navbar-shadow)'
}
}
}
}
```
## 🌐 国际化和主题系统
VGrove UI 提供了完整的国际化 (i18n) 支持和灵活的主题系统,让您的应用能够轻松适配不同语言和视觉风格。
### 国际化系统
#### I18nMessage 国际化消息组件
I18nMessage 组件用于显示多语言文本内容,支持变量插值和格式化。
```typescript
import { I18nMessage } from '@gulibs/vgrove-ui';
function WelcomeSection() {
const user = { name: '张三', points: 1250 };
return (
<div className="space-y-4">
{/* 基础消息 */}
<I18nMessage
id="welcome.title"
defaultValue="欢迎使用 VGrove UI"
/>
{/* 带变量插值的消息 */}
<I18nMessage
id="welcome.greeting"
defaultValue="您好,{name}!"
values={{ name: user.name }}
/>
{/* 复杂消息格式化 */}
<I18nMessage
id="user.points"
defaultValue="您当前有 {points, number} 积分"
values={{ points: user.points }}
/>
{/* 带有HTML的富文本消息 */}
<I18nMessage
id="terms.agreement"
defaultValue="我同意 <a href='/terms'>用户协议</a> 和 <a href='/privacy'>隐私政策</a>"
values={{
termsLink: (text) => <a href="/terms" className="text-primary">{text}</a>,
privacyLink: (text) => <a href="/privacy" className="text-primary">{text}</a>
}}
/>
{/* 带回退的消息 */}
<I18nMessage
id="feature.beta"
fallback="此功能正在测试中"
/>
</div>
);
}
```
#### I18nSwitch 语言切换组件
```typescript
import { I18nSwitch } from '@gulibs/vgrove-ui';
function LanguageControls() {
return (
<div className="flex items-center space-x-4">
{/* 下拉菜单样式 */}
<I18nSwitch
variant="dropdown"
supportedLanguages={[
{ code: 'zh-CN', name: '简体中文', flag: '🇨🇳' },
{ code: 'en-US', name: 'English', flag: '🇺🇸' },
{ code: 'ja-JP', name: '日本語', flag: '🇯🇵' }
]}
onLanguageChange={(language) => {
console.log('语言切换到:', language);
}}
/>
{/* 按钮组样式 */}
<I18nSwitch
variant="buttons"
supportedLanguages={[
{ code: 'zh-CN', name: '中', flag: '🇨🇳' },
{ code: 'en-US', name: 'EN', flag: '🇺🇸' }
]}
/>
</div>
);
}
```
### 主题系统
#### useTheme Hook
```typescript
import { useTheme } from '@gulibs/vgrove-ui';
function ThemeControls() {
const {
theme, // 当前主题设置
resolvedTheme, // 解析后的实际主题
setTheme, // 设置主题函数
toggleTheme, // 切换明暗主题
isDark, // 是否为暗色主题
isSystem // 是否跟随系统
} = useTheme();
return (
<div className="space-y-4">
<div className="flex space-x-2">
<Button
onClick={() => setTheme('light')}
variant={theme === 'light' ? 'solid' : 'flat'}
>
浅色
</Button>
<Button
onClick={() => setTheme('dark')}
variant={theme === 'dark' ? 'solid' : 'flat'}
>
深色
</Button>
<Button
onClick={() => setTheme('system')}
variant={theme === 'system' ? 'solid' : 'flat'}
>
跟随系统
</Button>
</div>
<Button onClick={toggleTheme}>
切换到{isDark ? '浅色' : '深色'}主题
</Button>
</div>
);
}
```
#### ThemeSwitch 主题切换器
```typescript
import { ThemeSwitch } from '@gulibs/vgrove-ui';
function ThemeSelectors() {
return (
<div className="space-x-4">
{/* 开关样式 */}
<ThemeSwitch variant="switch" showLabel={true} />
{/* 下拉菜单样式 */}
<ThemeSwitch variant="dropdown" enableSystem={true} />
{/* 圆形按钮样式 */}
<ThemeSwitch variant="circle" />
{/* 按钮组样式 */}
<ThemeSwitch variant="buttons" enableSystem={true} />
</div>
);
}
```
## 🎣 Hooks 和高级功能
VGrove UI 提供了丰富的自定义 Hooks 和高级功能,帮助您构建更强大和灵活的应用。
### VGrove 核心 Hooks
#### useVGrove - 核心上下文 Hook
useVGrove 提供对 VGrove 应用上下文的访问,包括布局设置和全局状态管理。
```typescript
import { useVGrove } from '@gulibs/vgrove-ui';
function LayoutController() {
const {
settings, // 当前布局设置
updateSettings, // 更新设置函数
resetSettings // 重置设置函数
} = useVGrove();
const toggleSidebar = () => {
updateSettings({
sidebar: {
...settings.sidebar,
collapsed: !settings.sidebar?.collapsed
}
});
};
return (
<div className="space-y-4">
<Switch
isSelected={!settings.sidebar?.collapsed}
onValueChange={toggleSidebar}
>
侧边栏: {settings.sidebar?.collapsed ? '已折叠' : '已展开'}
</Switch>
<Button onClick={resetSettings} color="warning">
重置布局设置
</Button>
</div>
);
}
```
### 表单相关 Hooks
#### useWatch / useFieldValue - 表单字段监听
```typescript
import { useWatch, useFieldValue, useFieldsWatcher } from '@gulibs/vgrove-ui';
function FormWatcher() {
// 监听单个字段
const username = useFieldValue('username');
// 监听多个字段
const [firstName, lastName] = useWatch(['firstName', 'lastName']);
// 监听字段状态
const { allFilled, anyFilled } = useFieldsWatcher(['name', 'email']);
return (
<div className="space-y-2">
<p>用户名: {username || '未填写'}</p>
<p>全名: {firstName && lastName ? `${firstName} ${lastName}` : '未完整'}</p>
<p>状态: {allFilled ? '完成' : anyFilled ? '部分完成' : '未开始'}</p>
</div>
);
}
```
### 高级功能
#### 调试配置
```typescript
import { updateDebugConfig } from '@gulibs/vgrove-ui';
// 开发环境启用调试
if (process.env.NODE_ENV === 'development') {
updateDebugConfig({
enabled: true,
auth: true, // 认证调试
loader: true, // Loader 调试
action: true, // Action 调试
routing: true, // 路由调试
performance: true // 性能监控
});
}
```
#### 存储管理
```typescript
import { useStorage } from '@gulibs/vgrove-ui';
function UserSettings() {
const {
value: settings,
setValue: setSettings,
remove: removeSettings
} = useStorage('user-settings', {
theme: 'light',
language: 'zh-CN'
});
return (
<div className="space-y-4">
<Select
value={settings.theme}
onChange={(e) => setSettings({
...settings,
theme: e.target.value
})}
>
<option value="light">浅色</option>
<option value="dark">深色</option>
</Select>
<Button onClick={removeSettings} color="warning">
重置设置
</Button>
</div>
);
}
```
## 📚 类型定义和 API 参考
### 表单相关 API
#### 函数和工具
```typescript
// 创建 FormInstance
function createFormInstance<TFieldValues extends FieldValues = FieldValues>(
formReturn: UseFormReturn<TFieldValues>
): FormInstance<TFieldValues>
// 增强的 useForm Hook
function useForm<TFieldValues extends FieldValues = FieldValues>(
options?: CustomUseFormProps<TFieldValues>
): FormInstance<TFieldValues>
// 注册全局 FormInstance
function registerFormInstance(instance: FormInstance<any>, key?: string): void
// 注销全局 FormInstance
function unregisterFormInstance(key?: string): void
// 获取全局 FormInstance
function getFormInstance(key?: string): FormInstance<any> | null
// 字段值监听
function useFieldValue<TFieldValues extends FieldValues = FieldValues>(
name: FieldPath<TFieldValues>,
control?: Control<TFieldValues>
): any
// 多字段监听
function useFieldsWatcher<TFieldValues extends FieldValues = FieldValues>(
names: FieldPath<TFieldValues>[],
control?: Control<TFieldValues>
): FieldsWatcherResult
// 字段更新工具
function useFieldUpdate<T = Element>(name: string): FieldUpdateResult<T>
// 获取表单上下文 (返回 FormInstance)
function useFormContext<TFieldValues extends FieldValues = FieldValues>(): FormInstance<TFieldValues>
// 可选获取表单上下文
function useFormContextOptional<TFieldValues extends FieldValues = FieldValues>(): FormInstance<TFieldValues> | null
// 检测是否在 FormProvider 内部
function useIsInsideFormProvider(): boolean
// 获取可用的 FormInstance
function useAvailableFormInstance<TFieldValues extends FieldValues = FieldValues>(): FormInstance<TFieldValues> | null
```
### 核心类型
#### 用户和认证相关
```typescript
// 基础用户类型
interface BaseUser {
id: string | number;
username?: string;
email?: string;
name?: string;
avatar?: string;
roles?: string[];
permissions?: string[];
[key: string]: any;
}
// 认证配置
interface AuthConfig {
authCheck: () => Promise<BaseUser | null> | BaseUser | null;
roleCheck?: (user: BaseUser, roles: string[]) => boolean;
permissionCheck?: (user: BaseUser, permissions: string[]) => boolean;
loginPath?: string;
forbiddenPath?: string;
publicPaths?: string[];
}
```
#### 表单相关类型
```typescript
// FormInstance 接口定义
interface FormInstance<TFieldValues extends FieldValues = FieldValues>
extends UseFormReturn<TFieldValues> {
// 基础方法
getFieldValue: (name: FieldPath<TFieldValues>) => any;
getFieldsValue: () => TFieldValues;
setFieldValue: (name: FieldPath<TFieldValues>, value: