Timeline 时间线
可视化地呈现时间流信息。
ts
import { createApp } from 'vue'
import { Timeline as ElTimeline, TimelineItem as ElTimelineItem } from '@szhn/dh-design-pc'
const app = createApp()
app.use(ElTimeline)
app.use(ElTimelineItem)基础用法
Timeline 可拆分成多个按照时间戳排列的活动,时间戳是其区分于其他控件的重要特征,使用时注意与 Steps 步骤条等区分。
<template>
<el-timeline>
<el-timeline-item
v-for="activity in activities"
:key="activity.content"
:timestamp="activity.timestamp"
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</template>
<script lang="ts" setup>
import { Timeline as ElTimeline, TimelineItem as ElTimelineItem } from '@szhn/dh-design-pc'
const activities = [
{ content: '创建成功', timestamp: '2024-01-01' },
{ content: '通过审核', timestamp: '2024-01-02' },
{ content: '活动按期开始', timestamp: '2024-01-03' },
]
</script>自定义节点样式
可根据实际场景自定义节点尺寸、颜色,或直接使用图标。
<template>
<el-timeline>
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
:type="activity.type"
:color="activity.color"
:size="activity.size"
:hollow="activity.hollow"
:timestamp="activity.timestamp"
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</template>
<script lang="ts" setup>
import { Timeline as ElTimeline, TimelineItem as ElTimelineItem } from '@szhn/dh-design-pc'
const activities = [
{ content: '默认节点', timestamp: '2024-04-12 20:46' },
{ content: '主节点', timestamp: '2024-04-03 20:46', type: 'primary' },
{ content: '成功节点', timestamp: '2024-04-03 20:46', type: 'success' },
{ content: '警告节点', timestamp: '2024-04-03 20:46', type: 'warning' },
{ content: '危险节点', timestamp: '2024-04-03 20:46', type: 'danger' },
{ content: '信息节点', timestamp: '2024-04-03 20:46', type: 'info' },
{ content: '自定义颜色', timestamp: '2024-04-03 20:46', color: '#0bbd87' },
{ content: '大尺寸', timestamp: '2024-04-03 20:46', size: 'large' },
{ content: '空心节点', timestamp: '2024-04-03 20:46', hollow: true },
]
</script>内容框
节点内容可放入卡片等内容容器,适合展示标题、说明和处理人等信息。
<template>
<el-timeline>
<el-timeline-item
v-for="item in items"
:key="item.title"
:timestamp="item.time"
placement="top"
>
<el-card>
<h4>{{ item.title }}</h4>
<p>{{ item.description }}</p>
</el-card>
</el-timeline-item>
</el-timeline>
</template>
<script lang="ts" setup>
import { Card as ElCard, Timeline as ElTimeline, TimelineItem as ElTimelineItem } from '@szhn/dh-design-pc'
const items = [
{
title: '节点名称',
time: '2026-01-01',
description: '事件简要描述',
},
{
title: '节点名称',
time: '2026-01-02',
description: '事件简要描述',
},
{
title: '节点名称',
time: '2026-01-03',
description: '事件简要描述',
},
]
</script>图标节点
通过 icon 属性或 dot 插槽可以替换默认节点图标。
<template>
<el-timeline>
<el-timeline-item timestamp="2024-04-01" placement="top">
<el-card>
<h4>更新 DHdesign 设计规范 v2.0</h4>
<p>提交者:Tom,提交时间:2024-04-01 20:46</p>
</el-card>
</el-timeline-item>
<el-timeline-item
timestamp="2024-04-03"
placement="top"
type="primary"
:icon="MoreFilled"
>
<el-card>
<h4>评审设计稿</h4>
<p>提交者:Tom,提交时间:2024-04-03 20:46</p>
</el-card>
</el-timeline-item>
</el-timeline>
</template>
<script lang="ts" setup>
import { Timeline as ElTimeline, TimelineItem as ElTimelineItem, Card as ElCard } from '@szhn/dh-design-pc'
import { MoreFilled } from '@szhn/dh-design-pc/icons'
</script>时间图标节点
当节点需要表达时间属性时,可使用时间图标替换默认圆点。
<template>
<el-timeline class="timeline-time-icon-demo">
<el-timeline-item v-for="item in items" :key="item.date">
<template #dot>
<span class="timeline-time-icon-demo__dot">
<svg viewBox="0 0 16 16" aria-hidden="true">
<circle cx="8" cy="8" r="6" />
<path d="M8 4.5V8l2.5 1.5" />
</svg>
</span>
</template>
<div class="timeline-time-icon-demo__title">{{ item.title }}</div>
<div class="timeline-time-icon-demo__date">{{ item.date }}</div>
<div class="timeline-time-icon-demo__desc">{{ item.description }}</div>
</el-timeline-item>
</el-timeline>
</template>
<script lang="ts" setup>
import { Timeline as ElTimeline, TimelineItem as ElTimelineItem } from '@szhn/dh-design-pc'
const items = [
{ title: '节点名称', date: '2026-01-01', description: '事件简要描述' },
{ title: '节点名称', date: '2026-01-01', description: '事件简要描述' },
{ title: '节点名称', date: '2026-01-01', description: '事件简要描述' },
{ title: '节点名称', date: '2026-01-01', description: '事件简要描述' },
]
</script>
<style scoped>
.timeline-time-icon-demo {
padding-left: 0;
}
.timeline-time-icon-demo :deep(.el-timeline-item) {
padding-bottom: 28px;
}
.timeline-time-icon-demo :deep(.el-timeline-item__dot) {
top: 5px;
left: 0;
width: 16px;
height: 16px;
color: var(--dh-color-text-disabled);
background-color: var(--dh-color-surface);
border: 0;
}
.timeline-time-icon-demo :deep(.el-timeline-item__tail) {
top: 31px;
left: 7px;
height: calc(100% - 31px);
}
.timeline-time-icon-demo :deep(.el-timeline-item__wrapper) {
padding-left: 28px;
}
.timeline-time-icon-demo__dot {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
color: var(--dh-color-text-disabled);
background-color: var(--dh-color-surface);
}
.timeline-time-icon-demo__dot svg {
width: 16px;
height: 16px;
overflow: visible;
fill: none;
stroke: currentColor;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.5;
}
.timeline-time-icon-demo__title {
color: var(--dh-color-text-primary);
font-size: var(--dh-font-size-base);
font-weight: var(--dh-font-weight-medium);
line-height: var(--dh-line-height-base);
}
.timeline-time-icon-demo__date {
margin-top: 2px;
color: var(--dh-color-text-placeholder);
font-size: var(--dh-font-size-sm);
line-height: var(--dh-line-height-sm);
}
.timeline-time-icon-demo__desc {
margin-top: 12px;
padding: 10px 16px;
color: var(--dh-color-text-secondary);
font-size: var(--dh-font-size-sm);
line-height: var(--dh-line-height-sm);
background-color: var(--dh-color-surface-soft);
border-radius: var(--dh-radius-base);
}
</style>时间戳位置
通过 placement 属性设置时间戳位置,可选 top 或 bottom(默认)。
<template>
<el-timeline>
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
:timestamp="activity.timestamp"
placement="top"
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</template>
<script lang="ts" setup>
import { Timeline as ElTimeline, TimelineItem as ElTimelineItem } from '@szhn/dh-design-pc'
const activities = [
{ content: '需求评审', timestamp: '2024-01-01 09:00' },
{ content: '技术设计', timestamp: '2024-01-02 10:30' },
{ content: '开发联调', timestamp: '2024-01-05 18:00' },
{ content: '正式上线', timestamp: '2024-01-10 14:20' },
]
</script>布局方式
Timeline 默认纵向展示。需要横向展示时,可基于时间线节点结构增加横向样式。
<template>
<div class="timeline-layout-demo">
<section>
<h4>纵向布局</h4>
<el-timeline>
<el-timeline-item
v-for="item in items"
:key="`vertical-${item.time}`"
:timestamp="item.time"
>
{{ item.title }}
</el-timeline-item>
</el-timeline>
</section>
<section>
<h4>横向展示</h4>
<div class="dh-timeline-horizontal-wrap">
<el-timeline class="dh-timeline-horizontal">
<el-timeline-item
v-for="item in items"
:key="`horizontal-${item.time}`"
:timestamp="item.time"
>
{{ item.title }}
</el-timeline-item>
</el-timeline>
</div>
</section>
</div>
</template>
<script lang="ts" setup>
import { Timeline as ElTimeline, TimelineItem as ElTimelineItem } from '@szhn/dh-design-pc'
const items = [
{ title: '节点名称', time: '2026-01-01' },
{ title: '节点名称', time: '2026-01-02' },
{ title: '节点名称', time: '2026-01-03' },
{ title: '节点名称', time: '2026-01-04' },
]
</script>
<style scoped>
.timeline-layout-demo {
display: grid;
gap: 28px;
}
.timeline-layout-demo h4 {
margin: 0 0 16px;
color: var(--dh-color-text-primary);
font-size: var(--dh-font-size-base);
font-weight: var(--dh-font-weight-medium);
}
.dh-timeline-horizontal-wrap {
overflow-x: auto;
padding-bottom: 4px;
}
.dh-timeline-horizontal {
display: grid;
grid-template-columns: repeat(4, minmax(160px, 1fr));
gap: 0;
min-width: 640px;
padding: 12px 0 0;
}
.dh-timeline-horizontal :deep(.el-timeline-item) {
min-width: 0;
padding: 0;
}
.dh-timeline-horizontal :deep(.el-timeline-item__tail) {
top: 7px;
left: calc(50% + 12px);
width: calc(100% - 24px);
height: 0;
border-left: 0;
border-top: var(--dh-timeline-line-width) solid var(--dh-timeline-line-color);
}
.dh-timeline-horizontal :deep(.el-timeline-item.is-start .el-timeline-item__tail) {
left: calc(50% + 12px);
}
.dh-timeline-horizontal :deep(.el-timeline-item:last-child .el-timeline-item__tail) {
display: none;
}
.dh-timeline-horizontal :deep(.el-timeline-item__node) {
top: 4px;
left: calc(50% - 4px);
}
.dh-timeline-horizontal :deep(.el-timeline-item.is-start .el-timeline-item__node--normal),
.dh-timeline-horizontal :deep(.el-timeline-item.is-start .el-timeline-item__node--large),
.dh-timeline-horizontal :deep(.el-timeline-item.is-start .el-timeline-item__node:not(:empty)) {
left: calc(50% - 4px);
}
.dh-timeline-horizontal :deep(.el-timeline-item__wrapper) {
top: 0;
padding-top: 24px;
padding-left: 0;
text-align: center;
}
.dh-timeline-horizontal :deep(.el-timeline-item.is-start .el-timeline-item__wrapper) {
padding-left: 0;
}
.dh-timeline-horizontal :deep(.el-timeline-item__timestamp.is-bottom) {
margin-top: 2px;
}
</style>反向
使用 reverse 属性来控制节点的顺序。
<template>
<div>
<el-switch v-model="reverse" />
<span style="margin-left: 8px;">reverse</span>
<el-timeline style="margin-top: 12px;">
<el-timeline-item
v-for="(activity, index) in list"
:key="index"
:timestamp="activity.timestamp"
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</div>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { Timeline as ElTimeline, TimelineItem as ElTimelineItem, Switch as ElSwitch } from '@szhn/dh-design-pc'
const reverse = ref(true)
const activities = [
{ content: 'Success', timestamp: '2018-04-11' },
{ content: 'Approved', timestamp: '2018-04-13' },
{ content: 'Success', timestamp: '2018-04-15' },
]
const list = computed(() =>
reverse.value ? [...activities].reverse() : activities,
)
</script>API
Timeline Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| mode | 时间线与内容的相对位置 | enum(start / end / alternate / alternate-reverse) | start |
| reverse | 是否反向排序节点 | boolean | false |
TimelineItem Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| timestamp | 时间戳 | string | — |
| hide-timestamp | 是否隐藏时间戳 | boolean | false |
| center | 时间戳是否垂直居中 | boolean | false |
| placement | 时间戳位置 | enum(top / bottom) | bottom |
| type | 节点类型 | enum(primary / success / warning / danger / info) | — |
| color | 节点颜色 | string | — |
| size | 节点尺寸 | enum(normal / large) | normal |
| icon | 节点自定义图标 | Component | — |
| hollow | 是否空心节点 | boolean | false |
TimelineItem Slots
| 插槽名 | 说明 |
|---|---|
| default | 自定义内容 |
| dot | 自定义节点 |
更多细节参见 Element Plus Timeline 文档。
