# 🦟 蚊子项目 - React组件库 这是蚊子项目的React组件库,提供完整的分享功能集成。 ## 📦 安装 ```bash npm install @mosquito/react # 或 yarn add @mosquito/react # 或 pnpm add @mosquito/react ``` ## 🚀 快速开始 ### 基础配置 ```typescript // src/index.tsx import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import { MosquitoProvider } from '@mosquito/react' const root = ReactDOM.createRoot(document.getElementById('root')!) root.render( ) ``` ## 📖 组件文档 ### MosquitoShareButton 分享按钮组件,支持一键复制链接到剪贴板。 #### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | activityId | `number` | - | 活动ID(必需) | | userId | `number` | - | 用户ID(必需) | | template | `string` | 'default' | 分享模板 | | text | `string` | '分享给好友' | 按钮文字 | | variant | `'primary'\|'secondary'\|'success'\|'danger'` | 'primary' | 按钮样式 | | size | `'sm'\|'md'\|'lg'` | 'md' | 按钮大小 | | disabled | `boolean` | false | 是否禁用 | #### Events | 事件 | 参数 | 说明 | |------|------|------| | onCopy | - | 链接已复制到剪贴板 | | onError | `Error` | 获取分享链接失败 | #### 示例 ```tsx import { MosquitoShareButton } from '@mosquito/react' import { useState } from 'react' function SharePage() { const activityId = 1 const userId = 100 const [message, setMessage] = useState('') return (
setMessage('分享链接已复制到剪贴板')} onError={(error) => setMessage(`错误: ${error.message}`)} /> {message &&

{message}

}
) } ``` ### MosquitoPosterCard 海报展示组件,支持加载状态和错误处理。 #### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | activityId | `number` | - | 活动ID(必需) | | userId | `number` | - | 用户ID(必需) | | template | `string` | 'default' | 海报模板 | | width | `string` | '300px' | 宽度 | | height | `string` | '400px' | 高度 | | lazy | `boolean` | false | 是否懒加载 | #### Events | 事件 | 参数 | 说明 | |------|------|------| | onLoad | - | 海报加载完成 | | onError | `Error` | 海报加载失败 | | onClick | - | 海报被点击 | #### 示例 ```tsx import { MosquitoPosterCard } from '@mosquito/react' import { useState } from 'react' function PosterPage() { const activityId = 1 const userId = 100 const [loading, setLoading] = useState(true) return (
setLoading(false)} onError={(error) => console.error('海报加载失败:', error)} onClick={() => console.log('海报被点击')} /> {loading &&

加载中...

}
) } ``` ### MosquitoLeaderboard 排行榜组件,支持分页和排序。 #### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | activityId | `number` | - | 活动ID(必需) | | page | `number` | 0 | 页码 | | pageSize | `number` | 20 | 每页大小 | | topN | `number` | undefined | 只显示前N名 | | currentUserId | `number` | undefined | 当前用户ID | | sortable | `boolean` | false | 是否支持排序 | | exportable | `boolean` | false | 是否显示导出按钮 | #### Events | 事件 | 参数 | 说明 | |------|------|------| | onLoad | `entries[]` | 排行榜数据加载完成 | | onError | `Error` | 排行榜加载失败 | | onPageChange | `number` | 页码变化 | | onExport | - | 导出排行榜 | #### 示例 ```tsx import { MosquitoLeaderboard } from '@mosquito/react' import { useState } from 'react' function LeaderboardPage() { const activityId = 1 const [page, setPage] = useState(0) const currentUserId = 100 return (
console.log('加载完成:', entries)} onError={(error) => console.error('加载失败:', error)} onPageChange={(newPage) => setPage(newPage)} onExport={() => console.log('导出排行榜')} />
) } ``` ### MosquitoShareModal 分享弹窗组件,提供多种分享方式。 #### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | activityId | `number` | - | 活动ID(必需) | | userId | `number` | - | 用户ID(必需) | | open | `boolean` | - | 是否打开 | | onClose | `() => void` | - | 关闭回调 | | title | `string` | '分享活动' | 弹窗标题 | #### 示例 ```tsx import { MosquitoShareModal } from '@mosquito/react' import { useState } from 'react' function ShareModalPage() { const activityId = 1 const userId = 100 const [open, setOpen] = useState(false) return (
setOpen(false)} />
) } ``` ## 🔧 Hooks ### useMosquito 核心Hook,提供API调用功能。 ```typescript import { useMosquito } from '@mosquito/react' function MyComponent() { const { // 活动管理 getActivity, createActivity, // 分享功能 getShareUrl, getShareMeta, // 海报功能 getPosterImage, getPosterHtml, // 排行榜 getLeaderboard, exportLeaderboard, // 状态 loading, error, // 配置 config } = useMosquito() const handleGetShareUrl = async () => { try { const url = await getShareUrl(1, 100) console.log('分享链接:', url) } catch (err) { console.error('获取分享链接失败:', err) } } return ( ) } ``` ### useShareUrl 获取分享链接的专用Hook。 ```typescript import { useShareUrl } from '@mosquito/react' function ShareUrlComponent({ activityId, userId }: { activityId: number; userId: number }) { const { shareUrl, loading, error, fetchShareUrl } = useShareUrl(activityId, userId) return (
{loading &&

加载中...

} {error &&

错误: {error.message}

} {shareUrl && (

分享链接: {shareUrl}

)}
) } ``` ### usePoster 海报功能的专用Hook。 ```typescript import { usePoster } from '@mosquito/react' function PosterComponent({ activityId, userId }: { activityId: number; userId: number }) { const { posterUrl, loading, error, fetchPoster } = usePoster(activityId, userId, 'default') return (
{loading &&

加载中...

} {error &&

错误: {error.message}

} {posterUrl && (
分享海报
)}
) } ``` ### useLeaderboard 排行榜的专用Hook。 ```typescript import { useLeaderboard } from '@mosquito/react' function LeaderboardComponent({ activityId }: { activityId: number }) { const { entries, loading, error, pagination, fetchLeaderboard, changePage } = useLeaderboard(activityId) return (
{loading &&

加载中...

} {error &&

错误: {error.message}

} {entries && (
第 {pagination.page + 1} 页
)}
) } ``` ## 🎨 自定义主题 ### 使用主题提供者 ```tsx import { MosquitoProvider, MosquitoTheme } from '@mosquito/react' const customTheme: MosquitoTheme = { colors: { primary: '#ff6b00', secondary: '#6c757d', success: '#28a745', danger: '#dc3545', warning: '#ffc107', }, components: { Button: { borderRadius: '8px', boxShadow: '0 2px 4px rgba(0,0,0,0.1)', }, Card: { borderRadius: '12px', boxShadow: '0 4px 8px rgba(0,0,0,0.15)', }, }, } function App() { return ( ) } ``` ## 📝 TypeScript类型 ### 类型定义 ```typescript import type { Activity, LeaderboardEntry, ShareMeta, PosterConfig, ApiResponse, MosquitoConfig, MosquitoTheme } from '@mosquito/react' // Activity类型 interface Activity { id: number name: string startTime: Date endTime: Date status: 'draft' | 'active' | 'completed' } // LeaderboardEntry类型 interface LeaderboardEntry { userId: number userName: string score: number rank?: number inviteCount?: number } // ShareMeta类型 interface ShareMeta { title: string description: string image: string url: string } // PosterConfig类型 interface PosterConfig { template: string imageUrl: string htmlUrl: string } // ApiResponse类型 interface ApiResponse { code: number message: string data: T meta?: { page: number size: number total: number totalPages: number } } // MosquitoConfig类型 interface MosquitoConfig { baseUrl: string apiKey: string timeout?: number retryCount?: number enableLogging?: boolean theme?: MosquitoTheme } // MosquitoTheme类型 interface MosquitoTheme { colors: { primary: string secondary: string success: string danger: string warning: string } components: { Button?: React.CSSProperties Card?: React.CSSProperties } } ``` ## 🧪 测试 ### 单元测试 ```typescript import { render, screen, fireEvent } from '@testing-library/react' import { MosquitoProvider } from '@mosquito/react' import { MosquitoShareButton } from '@mosquito/react' function renderWithProviders(ui: React.ReactElement) { return render( {ui} ) } test('渲染分享按钮', () => { renderWithProviders( ) const button = screen.getByText('分享给好友') expect(button).toBeInTheDocument() }) test('点击按钮触发分享', async () => { renderWithProviders( ) const button = screen.getByText('分享给好友') fireEvent.click(button) await waitFor(() => { expect(mockOnCopy).toHaveBeenCalled() }) }) ``` ## 📚 最佳实践 ### 1. 错误处理 ```tsx function GoodErrorHandling() { const { getShareUrl, error } = useMosquito() const [localError, setLocalError] = useState(null) const handleShare = async () => { try { await getShareUrl(1, 100) } catch (err) { setLocalError(err as Error) } } return (
{(error || localError) && (
{(error || localError)?.message}
)}
) } ``` ### 2. 加载状态 ```tsx function GoodLoadingState() { const { getShareUrl, loading } = useMosquito() return ( ) } ``` ### 3. 类型安全 ```tsx function TypeSafeComponent() { const [activity, setActivity] = useState(null) const { getActivity } = useMosquito() useEffect(() => { const loadActivity = async () => { const data = await getActivity(1) setActivity(data) } loadActivity() }, [getActivity]) return (
{activity && (

{activity.name}

开始时间: {activity.startTime.toLocaleDateString()}

结束时间: {activity.endTime.toLocaleDateString()}

)}
) } ``` ## 🤝 贡献 欢迎提交Issue和Pull Request! --- *React组件库版本: v2.0.0* *最后更新: 2026-01-22*