左侧历史对话模块:使用 Conversations 搭建会话入口
左侧åå²å¯¹è¯æ¨¡åï¼ä½¿ç¨ Conversations æå»ºä¼è¯å ¥å£
one_last_FE 2026-08-18 0 é 读6åé左侧åå²å¯¹è¯æ¨¡åï¼ä½¿ç¨ Conversations æå»ºä¼è¯å ¥å£
åè¨
å¨ AI å·¥ä½å°éï¼å·¦ä¾§é叏伿ä¸ä¸ªä¼è¯å表ã
å®çä½ç¨ç±»ä¼¼å¾å¤ AI 产åéçåå²è®°å½åºåï¼
左侧鿩ä¼è¯
ä¸é´å±ç¤ºå½åä¼è¯å
容
å¨å½å项ç®ä¸ï¼å·¦ä¾§åºå䏿¯èªå·±ä»é¶åå表ï¼èæ¯åºäº Ant Design X Vue æä¾ç Conversations ç»ä»¶å®ç°ã
è¿ç¯æç« ç®åä»ç»ä¸ä¸ï¼
- 左侧åå²å¯¹è¯æ¨¡åæ¯åä»ä¹çï¼
- 为ä»ä¹ç¨äº
Conversationsï¼- å½å页颿åªäºåè½ï¼
- 对åºä»£ç å¨åªéï¼
- å¦ä½ä½¿ç¨è¿ä¸ªç»ä»¶ã
模åä½ç½®
左侧åå²å¯¹è¯æ¨¡å对åºçæä»¶æ¯ï¼
src/features/workbench/components/HistoryPanel.vue
å®è¢«å·¥ä½å°é¡µé¢ä½¿ç¨ï¼
src/pages/workbench/WorkbenchPage.vue
æ´ä½å ³ç³»å¯ä»¥çè§£æï¼
WorkbenchPage
âââ HistoryPanel 左侧åå²å¯¹è¯
âââ ChatWorkspace ä¸é´ AI 对è¯åº
âââ InspectorPanel å³ä¾§è¿ç¨å产ç©åº
HistoryPanel åªè´è´£å·¦ä¾§åºåã
å®ä¸è´è´£çæ£ä¿åææä¸å¡æ°æ®ï¼æ°æ®ä¸»è¦ç±ç¶ç»ä»¶ WorkbenchPage ç»´æ¤ã
å½å左侧å å«ä»ä¹
å½å左侧主è¦å å«ååï¼
æ°å»ºåºç¨æé®
æç´¢æ¡
è½åå
¥å£
åå²å¯¹è¯
页é¢ç»æå¤§æ¦æ¯ï¼
å ¶ä¸ï¼
ChatåAI Codingæ¯é¢è®¾å¥½çè½åå ¥å£ï¼åå²å¯¹è¯æ¯ç¨æ·çå®å建æä¹ååå¨çä¼è¯ï¼- æ°å»ºåºç¨æ¶ï¼ä¼æ ¹æ®å½åéä¸çè½åå ¥å£å建ä¸åç±»åçä¼è¯ã
为ä»ä¹è¦åæè½åå ¥å£ååå²å¯¹è¯
宿¹ Conversations 示ä¾éï¼Help Me WriteãAI CodingãCreate Image æ´åæ¯é¢è®¾è½åå
¥å£ï¼è䏿¯åå²è®°å½æ¬èº«ã
æä»¥å½å项ç®ä¹æ¹æäºä¸¤å±ï¼
第ä¸å±ï¼è½åå
¥å£
第äºå±ï¼åå²å¯¹è¯
è¿æ ·æ´ç¬¦åçå®äº§åé»è¾ã
æ¯å¦ï¼
- ç¨æ·å
éæ©
Chatï¼ - ç¶åç¹å»æ°å»ºåºç¨ï¼
- ç³»ç»å建ä¸ä¸ªæ®é对è¯ç±»ä»»å¡ï¼
- ç¨æ·éæ©
AI Codingï¼ - åç¹å»æ°å»ºåºç¨ï¼
- ç³»ç»å建ä¸ä¸ªä»£ç ä¿®æ¹ç±»ä»»å¡ã
è½åå ¥å£å³å®âæ¥ä¸æ¥è¦å建ä»ä¹ç±»åçä¼è¯âãè°ç¨ä»ä¹æ¨¡åãä¸åçä»»å¡ä½¿ç¨ä¸å模åçææä¹æå·®å¼ï¼ä»·æ ¼ä¹ææå·®å¼
åå²å¯¹è¯å³å®âå½åæ£å¨æ¥çåªä¸ä¸ªå·²æä¼è¯âã
Conversations æ¯ä»ä¹
Conversations æ¯ Ant Design X Vue æä¾çä¼è¯å表ç»ä»¶ã
å®éåç¨æ¥åï¼
- åå²å¯¹è¯å表ï¼
- å¤ä¼è¯åæ¢ï¼
- Agent è½åå ¥å£ï¼
- ä¼è¯åç»å±ç¤ºã
å¨å½å项ç®éï¼æä»¬ç´æ¥å¼å ¥å®ï¼
import { Conversations } from 'ant-design-x-vue';
ç¶å卿¨¡æ¿é使ç¨ï¼
<Conversations
:items="conversationItems"
:activeKey="activeKey"
:groupable="true"
:onActiveChange="(key) => emit('activeChange', key)"
/>
å®ææ ¸å¿çå ä¸ªåæ°æ¯ï¼
| åæ° | ä½ç¨ |
|---|---|
items | åè¡¨æ°æ® |
activeKey | å½åéä¸çä¼è¯ |
groupable | æ¯å¦å¼å¯åç» |
onActiveChange | éä¸é¡¹ååæ¶è§¦å |
é¢è®¾è½åå ¥å£æä¹å
å½å项ç®éï¼é¢è®¾è½åå ¥å£æ¯è¿æ ·å®ä¹çï¼
const activeCapability = ref<WorkbenchCapability>('chat');
const capabilityItems = [
{
key: 'chat',
label: 'Chat',
icon: h(CommentOutlined),
},
{
key: 'coding',
label: 'AI Coding',
icon: h(CodeOutlined),
},
];
è¿éæä¸¤ä¸ªæ¦å¿µã
第ä¸ä¸ªæ¯ï¼
activeCapability
å®è¡¨ç¤ºå½åéä¸çè½åå ¥å£ã
é»è®¤å¼æ¯ï¼
'chat'
ä¹å°±æ¯é»è®¤éä¸ Chatã
第äºä¸ªæ¯ï¼
capabilityItems
å®å°±æ¯è¦å±ç¤ºçé¢è®¾å ¥å£æ°æ®ã
å½ååªæä¸¤ä¸ªï¼
Chat
AI Coding
ç¶åå¨é¡µé¢é使ç¨ï¼
<Conversations
:items="capabilityItems"
:activeKey="activeCapability"
:onActiveChange="handleCapabilityChange"
/>
è¿æ®µçæææ¯ï¼
- å±ç¤º
ChatåAI Codingï¼ - å½åéä¸é¡¹ç±
activeCapabilityæ§å¶ï¼ - ç¨æ·ç¹å»åæ¢æ¶ï¼è°ç¨
handleCapabilityChangeã
对åºå½æ°æ¯ï¼
const handleCapabilityChange = (key: string) => {
activeCapability.value = key as WorkbenchCapability;
};
å®çä½ç¨å°±æ¯ï¼
ç¨æ·ç¹å»åªä¸ªè½åå ¥å£ï¼å°±æå½åè½åæ¹æåªä¸ªã
åå²å¯¹è¯æä¹å
åå²å¯¹è¯çæ°æ®æ¥èªç¶ç»ä»¶ä¼ å ¥ï¼
const props = defineProps<{
items: ConversationItem[];
activeKey: string;
}>();
è¿éçï¼
items
表示ææåå²ä¼è¯ã
activeKey
表示å½åéä¸çåå²ä¼è¯ã
å 为ä¸å¡éçä¼è¯æ°æ®å段æ¯è¾å¤ï¼è Conversations ç»ä»¶åªéè¦ä¸é¨ååæ®µï¼æä»¥è¿éåäºä¸æ¬¡è½¬æ¢ï¼
const conversationItems = computed(() => props.items.map(item => ({
key: item.key,
label: item.label,
group: item.group,
icon: item.capability === 'coding' ? h(CodeOutlined) : h(CommentOutlined),
})));
è¿æ®µä»£ç çä½ç¨æ¯ï¼
æä¸å¡ä¼è¯æ°æ®è½¬æ¢æ
Conversationså¯ä»¥å±ç¤ºçæ°æ®ã
æ¯å¦åå§ä¼è¯æ°æ®å¯è½æ¯ï¼
{
key: 'landing-page',
label: 'ä¼ä¸å®ç½çæ',
group: 'ä»å¤©',
capability: 'chat',
description: 'é¦é¡µãæå¡ãè系表å',
status: 'done',
messages: []
}
转æ¢ä¹åä¼ ç» Conversations çæ°æ®æ¯ï¼
{
key: 'landing-page',
label: 'ä¼ä¸å®ç½çæ',
group: 'ä»å¤©',
icon: h(CommentOutlined)
}
ä¹å°±æ¯è¯´ï¼å·¦ä¾§å表åªå ³å¿ï¼
- å¯ä¸æ è¯ï¼
- å±ç¤ºåç§°ï¼
- åç»ï¼
- 徿 ã
å ¶ä»æ¶æ¯å 容ãæè¿°ãç¶æçåæ®µï¼ä¼çç»ä¸é´å¯¹è¯åºä½¿ç¨ã
åå²å¯¹è¯ç»ä»¶ä½¿ç¨
åå²å¯¹è¯å表对åºçæ¨¡æ¿æ¯ï¼
<Conversations
:items="conversationItems"
:activeKey="activeKey"
:groupable="true"
:onActiveChange="(key) => emit('activeChange', key)"
/>
è¿ééç¹çï¼
:groupable="true"
å®è¡¨ç¤ºå¼å¯åç»ã
å 为 conversationItems éæï¼
group: item.group
æä»¥åè¡¨ä¼æç
§ group å±ç¤ºã
å½å mock æ°æ®éæï¼
group: 'ä»å¤©'
åï¼
group: 'æ¨å¤©'
æä»¥å·¦ä¾§å°±ä¼å±ç¤ºæï¼
ä»å¤©
ä¼ä¸å®ç½çæ
ä½åéç½ç«
æ¨å¤©
åå页颿¹é
ç¹å»åå²å¯¹è¯æ¶åçäºä»ä¹
å½ç¨æ·ç¹å»ææ¡åå²å¯¹è¯æ¶ï¼ä¼è§¦åï¼
:onActiveChange="(key) => emit('activeChange', key)"
æææ¯ï¼
ç¨æ·ç¹å»äºææ¡ä¼è¯ï¼æè¿ä¸ªä¼è¯ç key ä¼ ç»ç¶ç»ä»¶ã
ç¶ç»ä»¶ WorkbenchPage ä¸è¿æ ·æ¥æ¶ï¼
<HistoryPanel
:items="conversations"
:activeKey="activeKey"
@activeChange="handleActiveChange"
@create="handleCreate"
/>
å ¶ä¸ï¼
const handleActiveChange = (key: string) => {
activeKey.value = key;
};
å®ä¼æå½åéä¸çä¼è¯ key æ¹æã
ç¶åä¸é´å¯¹è¯åºä¼æ ¹æ®æ°ç activeKey å±ç¤ºå¯¹åºçæ¶æ¯ã
宿´æµç¨æ¯ï¼
ç¨æ·ç¹å»åå²ä¼è¯
â
Conversations 触å onActiveChange
â
HistoryPanel emit('activeChange', key)
â
WorkbenchPage ä¿®æ¹ activeKey
â
ChatWorkspace å±ç¤ºæ°çä¼è¯å
容
ç¹å»æ°å»ºåºç¨æ¶åçäºä»ä¹
æ°å»ºæé®ä»£ç æ¯ï¼
<a-button type="primary" block @click="emit('create', activeCapability)">
<template #icon><PlusOutlined /></template>
æ°å»ºåºç¨
</a-button>
ä¸»è¦æ¯éç¥ç¶ç»ä»¶æ°å»ºåºç¨ï¼è¿éåªéè¦ç¥é大è´åè½ï¼å ·ä½å®ç°ä¼å¨ç¶ç»ä»¶ä»ç»ã
å½ååè½æ»ç»
å½å左侧åå²å¯¹è¯æ¨¡åå·²ç»å®ç°ï¼
- æ°å»ºåºç¨æé®ï¼
- æç´¢æ¡æ ·å¼é¢çï¼
- é¢è®¾è½åå ¥å£ï¼
Chatè½åï¼AI Codingè½åï¼- åå²ä¼è¯å表ï¼
- åå²ä¼è¯åç»ï¼
- å½åä¼è¯éä¸ï¼
- ç¹å»åå²ä¼è¯åæ¢ä¸é´å 容ï¼
- æ ¹æ®è½åå ¥å£å建ä¸åç±»åä¼è¯ã
å ¶ä¸ææ ¸å¿çç»ä»¶æ¯ï¼
Conversations
è¿ä¸ªç»ä»¶å¸®æä»¬çæäºå¾å¤éå¤å·¥ä½ï¼æ¯å¦å表渲æãéä¸ç¶æãåç»å±ç¤ºçã
æä»¬ä¸»è¦åçæ¯ï¼
- åå¤
itemsæ°æ®ï¼ - ç»´æ¤
activeKeyï¼ - çå¬
onActiveChangeï¼ - æ ¹æ®ä¸å¡éè¦åºåé¢è®¾å ¥å£ååå²å¯¹è¯ã
æ»ç»
左侧åå²å¯¹è¯æ¨¡åçæ ¸å¿æè·¯æ¯ï¼
使ç¨
Conversationsç»ä»¶ï¼æé¢è®¾è½åå ¥å£ååå²ä¼è¯å表ç»åèµ·æ¥ã
å½å项ç®ä¸ï¼ä¸åé¨åæ¯é¢è®¾è½åï¼
Chat
AI Coding
ä¸åé¨åæ¯çå®åå²å¯¹è¯ï¼
ä»å¤©
ä¼ä¸å®ç½çæ
ä½åéç½ç«
æ¨å¤©
åå页颿¹é
è¿æ ·æ¢ä¿çäºå®æ¹ç¤ºä¾éâé¢è®¾ itemâçè½åå ¥å£å½¢å¼ï¼ä¹æ»¡è¶³äºå®é AI å·¥ä½å°ä¸âåå²å¯¹è¯ç®¡çâçéæ±ã
Aitishiku.com