mirror of
https://github.com/lobehub/lobehub
synced 2026-04-22 01:57:22 +00:00
* feat: Redesign doc
* chore: uopdate site
* chore: uopdate site
* chore: uopdate site
* chore: uopdate site
* chore: uopdate site
* feat: Uopdate content
* chore: New doc
* chore: Update content
* chore: Update content
* chore: add images
* chore: add images
* chore: add images
* chore: add images
* feat: Add more images
* feat: Add more images
* fix: Cannot reach end
* chore: Update content
* chore: Update content
* chore: Update content
* chore: Update content
* chore: Update content
* Revise README content and structure
Updated README to reflect changes in project description and removed outdated notes.
* Revise 'Getting Started' and TOC in README
Updated the 'Getting Started' section and modified the table of contents.
* chore: Update content
* Revise README structure and content
Updated the Getting Started section and removed the Table of Contents. Adjusted the Local Development instructions.
* Remove custom themes section from README
Removed section about custom themes from README.
* Update README.md
* Refine introduction and highlight cloud version
Updated wording for clarity and added recommendation for cloud version.
* chore: Update content
* chore: Update content
* chore: Update content
* chore: Update content
* chore: Update content
* chore: Update content
* chore: Update content
* fix: add missing translation
* 🔀 chore: Move README changes to feat/readme branch
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add missing translation
* chore: update cdn
* docs: add migration guide from v1.x local database to v2.x and update help sections
Signed-off-by: Innei <tukon479@gmail.com>
* fix: add missing translation
* fix: add missing images
* fix: add missing changelogs
* fix: add missing changelogs
* fix: add missing changelogs
* fix: add missing changelogs
* fix: add missing changelogs
* style: update cdn
---------
Signed-off-by: Innei <tukon479@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: canisminor1990 <i@canisminor.cc>
Co-authored-by: Innei <tukon479@gmail.com>
142 lines
4.8 KiB
Text
142 lines
4.8 KiB
Text
---
|
||
title: 如何开发一个新功能:前端实现
|
||
description: 学习如何在 LobeHub 中实现会话消息功能,使用 Next.js 和 TypeScript。
|
||
tags:
|
||
- 前端开发
|
||
- Next.js
|
||
- TypeScript
|
||
- Zustand
|
||
- 功能实现
|
||
---
|
||
|
||
# 如何开发一个新功能:前端实现
|
||
|
||
LobeHub 基于 Next.js 框架构建,使用 TypeScript 作为主要开发语言。在开发新功能时,我们需要遵循一定的开发流程,以确保代码的质量和稳定性。大致的流程分为以下五步:
|
||
|
||
1. 路由:定义路由 (`src/app`)
|
||
2. 数据结构: 定义数据结构 ( `src/types` )
|
||
3. 业务功能实现: zustand store (`src/store`)
|
||
4. 页面展示:书写静态组件 / 页面。根据以下方式创建功能组件:
|
||
- `src/features/<feature-name>/` 用于 **全局共享功能**(跨多个页面使用)
|
||
- `src/app/<new-page>/features/<feature-name>/` 用于 **页面专属功能**(仅在当前页面使用)
|
||
5. 功能绑定:绑定 store 与页面的触发 (`const [state,function]= useNewStore(s=>[s.state,s.function])`)
|
||
|
||
我们以 "会话消息" 功能为例,以下是实现这个功能的简要步骤:
|
||
|
||
## 1. 定义路由
|
||
|
||
在 `src/app` 目录下,我们需要定义一个新的路由来承载 "会话消息" 页面。一般来说,我们会在 `src/app` 下创建一个新的文件夹,例如 `chat`,并且在这个文件夹中创建 `page.tsx`文件,在该文件中导出 React 组件作为页面的主体。
|
||
|
||
```tsx
|
||
// src/app/chat/page.tsx
|
||
import ChatPage from './features/chat';
|
||
|
||
export default ChatPage;
|
||
```
|
||
|
||
## 2. 定义数据结构
|
||
|
||
在 `src/types` 目录下,我们需要定义 "会话消息" 的数据结构。例如,我们创建一个 `chat.ts` 文件,并在其中定义 `ChatMessage` 类型:
|
||
|
||
```ts
|
||
// src/types/chat.ts
|
||
|
||
export type ChatMessage = {
|
||
id: string;
|
||
content: string;
|
||
timestamp: number;
|
||
sender: 'user' | 'bot';
|
||
};
|
||
```
|
||
|
||
## 3. 创建 Zustand Store
|
||
|
||
在 `src/store` 目录下,我们需要创建一个新的 Zustand Store 来管理 "会话消息" 的状态。例如,我们创建一个 `chatStore.ts` 文件,并在其中定义一个 Zustand Store:
|
||
|
||
```ts
|
||
// src/store/chatStore.ts
|
||
import { create } from 'zustand';
|
||
|
||
type ChatState = {
|
||
messages: ChatMessage[];
|
||
addMessage: (message: ChatMessage) => void;
|
||
};
|
||
|
||
export const useChatStore = create<ChatState>((set) => ({
|
||
messages: [],
|
||
addMessage: (message) => set((state) => ({ messages: [...state.messages, message] })),
|
||
}));
|
||
```
|
||
|
||
## 4. 创建页面与组件
|
||
|
||
在 `src/app/<new-page>/features/<new-feature>.tsx` 中,我们需要创建一个新的页面或组件来显示 "会话消息"。在这个文件中,我们可以使用上面创建的 Zustand Store,以及 Ant Design 的组件来构建 UI:
|
||
|
||
```jsx
|
||
// src/app/chat/features/ChatPage/index.tsx
|
||
// 注意:使用 src/app/<page>/features/ 放置页面专属组件
|
||
import { List, Typography } from 'antd';
|
||
import { useChatStore } from 'src/store/chatStore';
|
||
|
||
const ChatPage = () => {
|
||
const messages = useChatStore((state) => state.messages);
|
||
|
||
return (
|
||
<List
|
||
dataSource={messages}
|
||
renderItem={(message) => (
|
||
<List.Item>
|
||
<Typography.Text>{message.content}</Typography.Text>
|
||
|
||
</List.Item>
|
||
)}
|
||
/>
|
||
);
|
||
};
|
||
|
||
export default ChatPage;
|
||
```
|
||
|
||
> **关于功能组件组织方式的说明**:LobeHub 使用两种模式来组织功能组件:
|
||
>
|
||
> - **全局功能**(`src/features/`):跨应用共享的组件,如 `ChatInput`、`Conversation` 等
|
||
> - **页面专属功能**(`src/app/<page>/features/`):仅在特定页面路由中使用的组件
|
||
>
|
||
> 根据可复用性选择合适的方式。如果不确定,可以先放在页面专属位置,需要时再重构为全局共享。
|
||
|
||
## 5. 功能绑定
|
||
|
||
在页面或组件中,我们需要将 Zustand Store 的状态和方法绑定到 UI 上。在上面的示例中,我们已经将 `messages` 状态绑定到了列表的 `dataSource` 属性上。现在,我们还需要一个方法来添加新的消息。我们可以在 Zustand Store 中定义这个方法,然后在页面或组件中使用它:
|
||
|
||
```jsx
|
||
import { Button } from 'antd';
|
||
|
||
const ChatPage = () => {
|
||
const messages = useChatStore((state) => state.messages);
|
||
const addMessage = useChatStore((state) => state.addMessage);
|
||
|
||
const handleSend = () => {
|
||
addMessage({ id: '1', content: 'Hello, world!', timestamp: Date.now(), sender: 'user' });
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<List
|
||
dataSource={messages}
|
||
renderItem={(message) => (
|
||
<List.Item>
|
||
<Typography.Text>{message.content}</Typography.Text>
|
||
|
||
</List.Item>
|
||
)}
|
||
/>
|
||
<Button onClick={handleSend}>Send</Button>
|
||
|
||
</>
|
||
);
|
||
};
|
||
|
||
export default ChatPage;
|
||
```
|
||
|
||
以上就是在 LobeHub 中实现 "会话消息" 功能的步骤。当然,在 LobeHub 的实际开发中,真实场景所面临的业务诉求和场景远比上述 demo 复杂,请根据实际情况进行开发。
|