第5周:技术栈重构与项目架构设计

概述

在狼人杀项目的前端重构中,我选择了现代前端技术栈来构建一个响应式、可维护的游戏界面。本周的主要工作包括技术选型、项目初始化和基础架构搭建。

技术栈选择

核心框架

  • Vue 3 + Composition API:选择Vue 3是因为其优秀的响应式系统和Composition API提供的更好的代码组织能力,特别适合复杂的游戏状态管理。
  • TypeScript:使用TypeScript为项目带来了类型安全,特别是在处理游戏状态和API交互时,能够提前发现潜在错误。
  • Vite:作为构建工具,Vite提供了极快的开发体验和热更新速度,非常适合需要快速迭代的项目。

状态管理与路由

  • Pinia:作为Vue官方推荐的状态管理库,Pinia的API简洁直观,很好地支持了我们的会话状态管理需求。
  • Vue Router:用于处理大厅和游戏页面的路由切换。

UI组件库

  • Element Plus:提供了丰富的开箱即用组件,如按钮、输入框、选择器等,大大加快了UI开发速度。

HTTP客户端

  • Axios:用于与后端API进行通信,支持拦截器和请求取消等高级功能。

项目结构设计

frontend/
├── src/
│   ├── stores/
│   │   └── session.ts      # 游戏会话状态管理
│   ├── views/
│   │   ├── Lobby.vue       # 大厅页面
│   │   └── Game.vue        # 游戏主页面
│   ├── App.vue             # 根组件
│   ├── api.ts              # API层封装
│   ├── router.ts           # 路由配置
│   └── main.ts             # 入口文件
├── index.html
├── package.json
├── tsconfig.json
└── vite.config.ts

核心架构设计

1. API层设计 (api.ts)

将所有后端API调用统一封装在api.ts中,提供类型安全的函数接口:

// 创建会话
export async function createSession(): Promise<string> {
  const { data } = await API.post('/session')
  return data.thread_id
}

// 开始游戏,支持流式数据
export async function startGame(threadId: string, onMessage?: (data: any) => void) {
  return fetchStream('/start', { thread_id: threadId }, onMessage)
}

特别设计了fetchStream函数来处理SSE流式数据,这对于实时游戏体验至关重要:

async function fetchStream(url: string, body: any, onMessage?: (data: any) => void): Promise<any> {
  return new Promise((resolve, reject) => {
    fetch(`http://localhost:8000${url}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    }).then(async response => {
      const reader = response.body!.getReader()
      const decoder = new TextDecoder()
      let buffer = ''
      
      while (true) {
        const { done, value } = await reader.read()
        if (done) break
        
        buffer += decoder.decode(value, { stream: true })
        let lines = buffer.split('\n\n')
        buffer = lines.pop() || ''
        
        for (const line of lines) {
          if (line.startsWith('data: ')) {
            const dataStr = line.substring(6)
            const data = JSON.parse(dataStr)
            if (onMessage) onMessage(data)
            if (data.done) {
              resolve(data)
              return
            }
          }
        }
      }
      resolve(lastData || {})
    })
  })
}

2. 状态管理设计 (stores/session.ts)

使用Pinia创建会话状态管理store,集中管理游戏状态:

export const useSessionStore = defineStore('session', {
  state: () => ({
    threadId: '' as string,
    state: null as GameState | null,
    next: [] as string[],
    loading: false as boolean
  }),
  actions: {
    setThread(id: string) {
      this.threadId = id
      localStorage.setItem('thread_id', id)
    },
    setState(s: GameState, next: string[]) {
      this.state = s
      this.next = next || []
    },
    setLoading(v: boolean) {
      this.loading = v
    }
  }
})

3. 大厅页面 (Lobby.vue)

设计了现代化的大厅界面,包含:

  • 精美的渐变背景和装饰元素
  • 游戏特性展示卡片
  • 服务状态检查
  • 会话管理功能

4. 根组件设计 (App.vue)

提供统一的布局框架,包含顶部导航栏和路由视图容器,并进行了主题定制,覆盖Element Plus的默认样式以匹配项目设计语言。

本周收获

本周完成了前端项目的基础架构搭建,确立了清晰的代码组织规范,为后续功能开发奠定了坚实基础。选择Vue 3 + TypeScript + Pinia的组合,既保证了开发效率,又确保了代码质量和可维护性。

下周将重点实现游戏流程的可视化和复杂状态管理逻辑。

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐