《60天AI学习计划启动 | Day 38: 多会话 & 多 Tab 同步(前端层)》
Day 38:多会话 & 多 Tab 同步(前端层)
学习目标
- 设计 多会话模型:当前会话 + 会话列表(标题/摘要/时间)
- 掌握 利用
localStorage + storage 事件做多 Tab 状态同步 - 实现 简单的会话新建 / 重命名 / 归档逻辑
核心知识点
-
多会话数据模型
Session:{ id, title, updatedAt, archived }SessionMessages:Record<sessionId, Message[]>- Store 里需要:
currentSessionId + sessions[] + messagesBySession
-
多 Tab 同步
- 写入:每次会话/消息变化 →
localStorage.setItem('ai_sessions', JSON.stringify(...)) - 监听:
window.addEventListener('storage', handler),对同一域其他 Tab 生效 - 注意:当前 Tab 改变时也会写 localStorage,但
storage事件不会在当前 Tab 触发
- 写入:每次会话/消息变化 →
实战作业(附代码)
- 作业 1:多会话 TS 类型
export interface Session {
id: string
title: string
updatedAt: number
archived?: boolean
}
export interface Message {
id: string
role: 'user' | 'assistant'
content: string
createdAt: number
}
export interface SessionState {
sessions: Session[]
currentSessionId: string | null
messagesBySession: Record<string, Message[]>
}
- 作业 2:多 Tab 同步 hook(简化版)
import { useEffect } from 'react'
import type { SessionState } from './types'
const STORAGE_KEY = 'ai_chat_sessions'
export function saveStateToStorage(state: SessionState) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(state))
}
export function loadStateFromStorage(): SessionState | null {
const raw = localStorage.getItem(STORAGE_KEY)
if (!raw) return null
try {
return JSON.parse(raw)
} catch {
return null
}
}
export function useMultiTabSync(
state: SessionState,
setState: (s: SessionState) => void
) {
// 初始化:加载本地数据
useEffect(() => {
const stored = loadStateFromStorage()
if (stored) setState(stored)
}, [setState])
// 本 Tab 变化时写入 localStorage(可加节流)
useEffect(() => {
saveStateToStorage(state)
}, [state])
// 监听其他 Tab 的变更
useEffect(() => {
const handler = (e: StorageEvent) => {
if (e.key !== STORAGE_KEY || !e.newValue) return
try {
const next = JSON.parse(e.newValue) as SessionState
setState(next)
} catch {}
}
window.addEventListener('storage', handler)
return () => window.removeEventListener('storage', handler)
}, [setState])
}
- 作业 3:新建 / 重命名 / 归档会话 helpers
export function createSession(title = '新对话'): Session {
return { id: crypto.randomUUID(), title, updatedAt: Date.now() }
}
export function renameSession(s: Session, title: string): Session {
return { ...s, title, updatedAt: Date.now() }
}
export function archiveSession(s: Session): Session {
return { ...s, archived: true, updatedAt: Date.now() }
}
明日学习计划预告(Day 39)
- 主题:Agent 执行过程可视化
- 方向:
- 展示 Agent 的「思考 → 工具调用 → 观察 → 最终回答」步骤
- 设计一个简单的“执行轨迹”时间线组件

浙公网安备 33010602011771号