# 前端结构
本文档详细介绍 Vue 3 前端的代码结构、组件功能和状态管理。
## 目录结构
```
src/
├── api/ # Tauri 命令封装
│ └── index.ts
├── components/ # 可复用组件
│ ├── Sidebar.vue
│ ├── DeviceCard.vue
│ ├── MessageBubble.vue
│ ├── ChatInput.vue
│ ├── FileProgress.vue
│ └── LoadingSpinner.vue
├── pages/ # 页面组件
│ ├── DeviceList.vue
│ ├── ChatWindow.vue
│ ├── FileTransfer.vue
│ └── Settings.vue
├── stores/ # Pinia 状态管理
│ ├── deviceStore.ts
│ ├── chatStore.ts
│ └── settingsStore.ts
├── hooks/ # 组合式函数
│ ├── useEventListener.ts
│ └── useTheme.ts
├── types/ # TypeScript 类型
│ └── index.ts
├── router/ # Vue Router
│ └── index.ts
├── styles/ # 全局样式
│ └── main.css
├── App.vue # 根组件
└── main.ts # 入口文件
```
## 页面组件
### DeviceList.vue
设备列表页面,展示在线设备。
**功能**:
- 显示所有在线设备
- 点击设备进入聊天
- 自动刷新设备列表
**模板结构**:
```vue
```
### ChatWindow.vue
聊天窗口页面,与指定设备聊天。
**功能**:
- 显示聊天历史
- 发送/接收消息
- 发送文件
- 显示文件传输进度
- 点击文件消息打开文件位置
**关键逻辑**:
```typescript
// 过滤当前设备的传输(仅显示进行中)
const deviceTransfers = computed(() => {
const result: FileTransfer[] = []
for (const [, transfer] of chatStore.transfers) {
const isRelated =
(transfer.fromDevice === localDeviceId.value && transfer.toDevice === deviceId.value) ||
(transfer.fromDevice === deviceId.value && transfer.toDevice === localDeviceId.value)
const isInProgress = transfer.status === 'pending' || transfer.status === 'transferring'
if (isRelated && isInProgress) {
result.push(transfer)
}
}
return result
})
// 点击文件消息打开位置
async function handleFileClick(fileName: string) {
// 查找传输记录,获取 localPath
await chatStore.openFileLocation(transfer.localPath)
}
```
### FileTransfer.vue
文件传输页面,展示所有传输记录。
**功能**:
- 显示所有传输(进行中/已完成)
- 取消传输
- 打开文件位置
### Settings.vue
设置页面。
**功能**:
- 修改设备名称
- 切换主题(系统/浅色/深色)
- 修改下载目录
## 组件详解
### Sidebar.vue
侧边导航栏。
```vue
```
### DeviceCard.vue
设备卡片组件。
**Props**:
```typescript
interface Props {
device: DeviceInfo
}
```
**显示内容**:
- 设备名称
- IP 地址
- 在线状态指示
### MessageBubble.vue
消息气泡组件。
**Props**:
```typescript
interface Props {
message: ChatMessage
isOwn: boolean // 是否是自己发送的
}
```
**事件**:
```typescript
const emit = defineEmits<{
'file-click': [fileName: string]
}>()
```
**支持的消息类型**:
- `text`: 文本消息
- `image`: 图片消息
- `file`: 文件消息(可点击)
### ChatInput.vue
聊天输入框组件。
**事件**:
```typescript
const emit = defineEmits<{
'send': [content: string]
'send-file': []
}>()
```
**功能**:
- 文本输入
- Enter 发送
- 文件选择按钮
### FileProgress.vue
文件传输进度组件。
**Props**:
```typescript
interface Props {
transfer: FileTransfer
isReceiver: boolean // 是否是接收方
}
```
**显示内容**:
- 文件名
- 进度条
- 传输速度/状态
- 操作按钮(取消/打开位置)
### LoadingSpinner.vue
加载动画组件。
## 状态管理
### deviceStore.ts
管理设备相关状态。
```typescript
export const useDeviceStore = defineStore('device', () => {
// 状态
const devices = ref