Introduction
ThoughtChain is a timeline component used to display AI thinking processes, supporting state management, content expand/collapse, and dynamic style configuration. Through visual thinking step sequences, it helps users intuitively understand complex logical flows. The component has built-in multiple state feedback, transition animations, and extension slots, suitable for intelligent conversations, data analysis, process guidance, and other scenarios.
Code Examples
Basic Usage
- Success - Main TitleThinking Content Title - Default ExpandedSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Loading - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Failed - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Failed - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
Control rendering by passing an array through thinkingItems.
💌 Info
id is a required field. You can also set the unique identifier name through rowKey, default is id.
<script setup lang="ts">
import type { ThoughtChainItemProps } from 'vue-element-plus-x/types/ThoughtChain';
interface DataType {
codeId: string;
title?: string;
thinkTitle?: string;
thinkContent?: string;
status?: 'success' | 'loading' | 'error';
}
const thinkingItems: ThoughtChainItemProps<DataType>[] = [
{
id: '1',
codeId: '1',
status: 'success',
isCanExpand: true,
isDefaultExpand: true,
title: 'Success - Main Title',
thinkTitle: 'Thinking Content Title - Default Expanded',
thinkContent: 'Search text'.repeat(10)
},
{
id: '2',
codeId: '2',
title: 'Loading - Main Title',
status: 'loading',
isCanExpand: true,
isDefaultExpand: false,
thinkTitle: 'Thinking Content Title',
thinkContent: 'Search text'.repeat(10)
},
{
id: '3',
codeId: '3',
title: 'Failed - Main Title',
status: 'error',
isCanExpand: true,
isDefaultExpand: false,
thinkTitle: 'Thinking Content Title',
thinkContent: 'Search text'.repeat(10)
},
{
id: '4',
codeId: '4',
title: 'Failed - Main Title',
status: 'error',
isCanExpand: true,
isDefaultExpand: true,
thinkTitle: 'Thinking Content Title',
thinkContent: 'Search text'.repeat(10)
}
];
</script>
<template>
<ThoughtChain :thinking-items="thinkingItems" row-key="codeId" />
</template>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Dot Size Control
- Success - Main TitleThinking Content Title - Default ExpandedSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Loading - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Failed - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Hide Main Title, Thinking Content Title - Default ExpandedSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Success - Main TitleThinking Content Title - Default ExpandedSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Loading - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Failed - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Hide Main Title, Thinking Content Title - Default ExpandedSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
Default value is default, optional values are small, default, large.
<script setup lang="ts">
import type { ThoughtChainItemProps } from 'vue-element-plus-x/types/ThoughtChain';
interface DataType {
id: string;
title?: string;
thinkTitle?: string;
thinkContent?: string;
status?: 'success' | 'loading' | 'error';
hideTitle?: boolean;
}
const thinkingItems: ThoughtChainItemProps<DataType>[] = [
{
id: '1',
status: 'success',
isCanExpand: true,
isDefaultExpand: true,
title: 'Success - Main Title',
thinkTitle: 'Thinking Content Title - Default Expanded',
thinkContent: 'Search text'.repeat(10)
},
{
id: '2',
title: 'Loading - Main Title',
status: 'loading',
isCanExpand: true,
isDefaultExpand: false,
thinkTitle: 'Thinking Content Title',
thinkContent: 'Search text'.repeat(10)
},
{
id: '3',
title: 'Failed - Main Title',
status: 'error',
isCanExpand: true,
isDefaultExpand: false,
thinkTitle: 'Thinking Content Title',
thinkContent: 'Search text'.repeat(10)
},
{
id: '4',
hideTitle: true,
status: 'loading',
isCanExpand: true,
isDefaultExpand: true,
thinkTitle: 'Hide Main Title, Thinking Content Title - Default Expanded',
thinkContent: 'Search text'.repeat(10)
}
];
</script>
<template>
<ThoughtChain :thinking-items="thinkingItems" dot-size="small" />
<ThoughtChain :thinking-items="thinkingItems" dot-size="large" />
</template>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Max Width Control
- Success - Main TitleThinking Content Title - Default ExpandedSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
Set the maximum width of the thought chain, default is '500px'. String type, meaning you can pass percentages like '50%', or other units, even CSS calculated width like 'calc(100% - 200px)'.
<script setup lang="ts">
import type { ThoughtChainItemProps } from 'vue-element-plus-x/types/ThoughtChain';
interface DataType {
id: string;
title?: string;
thinkTitle?: string;
thinkContent?: string;
status?: 'success' | 'loading' | 'error';
hideTitle?: boolean;
}
const thinkingItems: ThoughtChainItemProps<DataType>[] = [
{
id: '1',
status: 'success',
isCanExpand: true,
isDefaultExpand: true,
title: 'Success - Main Title',
thinkTitle: 'Thinking Content Title - Default Expanded',
thinkContent: 'Search text'.repeat(20)
}
];
</script>
<template>
<ThoughtChain
:thinking-items="thinkingItems"
max-width="calc(100% - 300px)"
/>
</template>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Custom Title and Content
- Success - Main TitleThinking Content Title - Default ExpandedSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Loading - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Failed - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Thank You - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
Through the titleKey, thinkTitleKey, and thinkContentKey properties, you can customize the key names for: title, thinking content title, and thinking content of nodes.
<script setup lang="ts">
import type { ThoughtChainItemProps } from 'vue-element-plus-x/types/ThoughtChain';
interface DataType {
codeId: string;
self_title?: string;
self_thinkTitle?: string;
self_thinkContent?: string;
status?: 'success' | 'loading' | 'error';
}
const thinkingItems: ThoughtChainItemProps<DataType>[] = [
{
codeId: '1',
status: 'success',
isCanExpand: true,
isDefaultExpand: true,
self_title: 'Success - Main Title',
self_thinkTitle: 'Thinking Content Title - Default Expanded',
self_thinkContent: 'Search text'.repeat(10)
},
{
codeId: '2',
self_title: 'Loading - Main Title',
status: 'loading',
isCanExpand: true,
isDefaultExpand: false,
self_thinkTitle: 'Thinking Content Title',
self_thinkContent: 'Search text'.repeat(10)
},
{
codeId: '3',
self_title: 'Failed - Main Title',
status: 'error',
isCanExpand: true,
isDefaultExpand: false,
self_thinkTitle: 'Thinking Content Title',
self_thinkContent: 'Search text'.repeat(10)
},
{
codeId: '4',
self_title: 'Thank You - Main Title',
status: 'success',
isCanExpand: true,
isDefaultExpand: true,
self_thinkTitle: 'Thinking Content Title',
self_thinkContent: 'Search text'.repeat(10)
}
];
</script>
<template>
<ThoughtChain
:thinking-items="thinkingItems"
row-key="codeId"
title-key="self_title"
think-title-key="self_thinkTitle"
think-content-key="self_thinkContent"
/>
</template>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Extension Slots
- Success - Main TitleThinking Content Title - Default ExpandedSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Loading - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Failed - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Thank You - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
Through the #icon slot, you can customize icons for different states. You can get the current state through #icon={item}.
<script setup lang="ts">
import type { ThoughtChainItemProps } from 'vue-element-plus-x/types/ThoughtChain';
import {
CircleCloseFilled,
Loading,
SuccessFilled
} from '@element-plus/icons-vue';
interface DataType {
codeId: string;
self_title?: string;
self_thinkTitle?: string;
self_thinkContent?: string;
status?: 'success' | 'loading' | 'error';
}
const thinkingItems: ThoughtChainItemProps<DataType>[] = [
{
codeId: '1',
status: 'success',
isCanExpand: true,
isDefaultExpand: true,
self_title: 'Success - Main Title',
self_thinkTitle: 'Thinking Content Title - Default Expanded',
self_thinkContent: 'Search text'.repeat(10)
},
{
codeId: '2',
self_title: 'Loading - Main Title',
status: 'loading',
isCanExpand: true,
isDefaultExpand: false,
self_thinkTitle: 'Thinking Content Title',
self_thinkContent: 'Search text'.repeat(10)
},
{
codeId: '3',
self_title: 'Failed - Main Title',
status: 'error',
isCanExpand: true,
isDefaultExpand: false,
self_thinkTitle: 'Thinking Content Title',
self_thinkContent: 'Search text'.repeat(10)
},
{
codeId: '4',
self_title: 'Thank You - Main Title',
status: 'success',
isCanExpand: true,
isDefaultExpand: true,
self_thinkTitle: 'Thinking Content Title',
self_thinkContent: 'Search text'.repeat(10)
}
];
</script>
<template>
<ThoughtChain
:thinking-items="thinkingItems"
row-key="codeId"
title-key="self_title"
think-title-key="self_thinkTitle"
think-content-key="self_thinkContent"
>
<template #icon="{ item }">
<span
v-if="item.status === 'success'"
style="
font-size: 18px;
margin-left: 7px;
color: var(--el-color-success);
"
>
<el-icon><SuccessFilled /></el-icon>
</span>
<span
v-if="item.status === 'error'"
style="font-size: 18px; margin-left: 7px; color: var(--el-color-danger)"
>
<el-icon><CircleCloseFilled /></el-icon>
</span>
<span
v-if="item.status === 'loading'"
style="font-size: 18px; margin-left: 7px"
>
<el-icon class="is-loading"><Loading /></el-icon>
</span>
</template>
</ThoughtChain>
</template>
<style scoped lang="less">
.is-loading {
animation: spin 1s infinite linear;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
Manual Expand State Control
- Success - Main TitleThinking Content Title - Default ExpandedSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Loading - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Failed - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
- Thank You - Main TitleThinking Content TitleSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch textSearch text
Through the handleExpand event, you can get the currently expanded node data.
<script setup lang="ts">
import type { ThoughtChainItemProps } from 'vue-element-plus-x/types/ThoughtChain';
interface DataType {
codeId: string;
self_title?: string;
self_thinkTitle?: string;
self_thinkContent?: string;
status?: 'success' | 'loading' | 'error';
}
const thinkingItems: ThoughtChainItemProps<DataType>[] = [
{
codeId: '1',
status: 'success',
isCanExpand: true,
isDefaultExpand: true,
self_title: 'Success - Main Title',
self_thinkTitle: 'Thinking Content Title - Default Expanded',
self_thinkContent: 'Search text'.repeat(10)
},
{
codeId: '2',
self_title: 'Loading - Main Title',
status: 'loading',
isCanExpand: true,
isDefaultExpand: false,
self_thinkTitle: 'Thinking Content Title',
self_thinkContent: 'Search text'.repeat(10)
},
{
codeId: '3',
self_title: 'Failed - Main Title',
status: 'error',
isCanExpand: true,
isDefaultExpand: false,
self_thinkTitle: 'Thinking Content Title',
self_thinkContent: 'Search text'.repeat(10)
},
{
codeId: '4',
self_title: 'Thank You - Main Title',
status: 'success',
isCanExpand: true,
isDefaultExpand: true,
self_thinkTitle: 'Thinking Content Title',
self_thinkContent: 'Search text'.repeat(10)
}
];
function handleExpand(value: string[]) {
const expandedItems = thinkingItems.filter(item =>
value.includes(item.codeId)
);
console.log(expandedItems);
}
</script>
<template>
<ThoughtChain
:thinking-items="thinkingItems"
row-key="codeId"
title-key="self_title"
think-title-key="self_thinkTitle"
think-content-key="self_thinkContent"
@handle-expand="(value: string[]) => handleExpand(value)"
/>
</template>
<style scoped lang="less">
.is-loading {
animation: spin 1s infinite linear;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Attributes
- Component Attributes
| Parameter | Type | Default | Description |
|---|---|---|---|
thinkingItems | Array<ThoughtChainItemBase> | [] | Thinking items array |
dotSize | 'small'/'default'/'large' | 'default' | Timeline dot size |
maxWidth | string | '600px' | Maximum width |
lineGradient | boolean | false | Whether to enable line color gradient |
rowKey | string | 'id' | Data item unique identifier field |
titleKey | string | 'title' | Title field name |
thinkTitleKey | string | 'thinkTitle' | Thinking title field name |
thinkContentKey | string | 'thinkContent' | Thinking content field name |
- ThoughtChainItemBase Array item type definition
| Parameter | Type | Default | Description |
|---|---|---|---|
id | string | number | Required | Node unique identifier |
title | string | undefined | Main title |
thinkTitle | string | undefined | Collapse panel title (thinking title) |
thinkContent | string | undefined | Detailed content displayed when expanded |
status | 'loading' | 'error' | 'success' | undefined | Node status identifier (affects icon and color) |
isCanExpand | boolean | undefined | Whether to allow expanding node content |
isDefaultExpand | boolean | undefined | Whether to expand node content by default |
isMarkdown | boolean | undefined | Whether to enable Markdown format rendering |
typing | TypingConfig | undefined | Typewriter effect configuration (same as typewriter component) |
Events
| Event Name | Parameter Type | Description |
|---|---|---|
handleExpand | item: ThoughtChainItemProps<T> | Triggered when expand state changes |
Slots
| Slot Name | Scope Parameters | Description |
|---|---|---|
#icon | { item } | Custom timeline dot icon |
Core Features
Multi-state Visualization
- Supports
loading/success/error - Automatically switches loading animations, icons, and color feedback
- Supports
Dynamic Content Management
- Supports content collapse/expand (configurable default expanded items)
- Built-in typewriter effect (Typewriter component)
- Supports Markdown format rendering
Flexible Style Configuration
- Custom timeline width, dot size
- Dynamic color gradient lines
- CSS variable theme override
Responsive Interaction
- Smooth transition animations
- Supports dynamic addition/deletion of thinking items
- Two-way binding of expand state
