Appearance
BizVersionHistory 版本历史
版本历史时间轴:版本号 + 角标 + 当前版本标记(绿点 / 标签)、操作人 / 时间、版本说明(note 插槽可接管)、行内操作——查看 / 恢复此版本 / 对比(对比为两次点选 A/B 后 compare 外抛,可配合 BizDiffViewer 展示差异)。文档、报表、流程定义等资产的版本留痕与回滚入口。
基础用法
- v2.4.0当前版本最新2026-10-26 17:24李娜上线新版数据看板 修复 3 个体验问题
- v2.3.02026-10-23 11:24张伟新增批量导入导出能力
- v2.2.1热修2026-10-18 15:24王强紧急修复订单同步丢数问题
- v2.2.02026-10-11 10:24李娜权限体系升级为 RBAC 矩阵
版本时间轴:当前版本标记 + 操作人时间 + 说明 + 行内操作。
<script setup lang="ts">
/** 场景:基础——版本时间轴 + 当前版本标记 */
import { ElMessage } from 'element-plus'
import { BizVersionHistory } from 'vue3-ep-biz-lib'
import type { BizVersionItem } from 'vue3-ep-biz-lib'
const dayOf = (offset: number, h: number): string => {
const d = new Date()
d.setDate(d.getDate() - offset)
d.setHours(h, 24, 0, 0)
return d.toISOString()
}
const versions: BizVersionItem[] = [
{ id: 'v6', version: 'v2.4.0', author: '李娜', time: dayOf(0, 17), current: true, tags: ['最新'], note: '上线新版数据看板\n修复 3 个体验问题' },
{ id: 'v5', version: 'v2.3.0', author: '张伟', time: dayOf(3, 11), note: '新增批量导入导出能力' },
{ id: 'v4', version: 'v2.2.1', author: '王强', time: dayOf(8, 15), tags: ['热修'], note: '紧急修复订单同步丢数问题' },
{ id: 'v3', version: 'v2.2.0', author: '李娜', time: dayOf(15, 10), note: '权限体系升级为 RBAC 矩阵' },
]
</script>
<template>
<BizVersionHistory
:versions="versions"
@view="(v: BizVersionItem) => ElMessage.info(`查看 ${v.version}`)"
@restore="(v: BizVersionItem) => ElMessage.warning(`请求恢复 ${v.version}(demo 未执行)`)"
/>
</template>
显示代码
版本对比
- 报价方案 v3当前版本2026-10-26 14:00陈静总价下调 5%,赠送延保
- 报价方案 v22026-10-24 14:00陈静硬件配置升级
- 报价方案 v12026-10-20 14:00周明初版报价
最近对比:(未对比)
点两个版本的「对比」完成 A/B 选择,compare 外抛两版本。
<script setup lang="ts">
/** 场景:版本对比——两次点选 A/B */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizVersionHistory } from 'vue3-ep-biz-lib'
import type { BizVersionItem } from 'vue3-ep-biz-lib'
const dayOf = (offset: number): string => {
const d = new Date()
d.setDate(d.getDate() - offset)
d.setHours(14, 0, 0, 0)
return d.toISOString()
}
const versions: BizVersionItem[] = [
{ id: 'v3', version: '报价方案 v3', author: '陈静', time: dayOf(0), current: true, note: '总价下调 5%,赠送延保' },
{ id: 'v2', version: '报价方案 v2', author: '陈静', time: dayOf(2), note: '硬件配置升级' },
{ id: 'v1', version: '报价方案 v1', author: '周明', time: dayOf(6), note: '初版报价' },
]
const picked = ref('')
const onCompare = (a: BizVersionItem, b: BizVersionItem): void => {
picked.value = `${a.version} ↔ ${b.version}`
ElMessage.success(`对比 ${a.version} 与 ${b.version}(差异渲染交给 BizDiffViewer)`)
}
</script>
<template>
<div>
<BizVersionHistory :versions="versions" :max-height="340" @compare="onCompare" />
<p style="margin: 10px 0 0; font-size: 12px; color: var(--el-text-color-secondary)">
最近对比:{{ picked || '(未对比)' }}
</p>
</div>
</template>
显示代码
恢复确认
- 流程定义 v2当前版本系统
- 流程定义 v1系统
restore 事件配合二次确认(业务层执行回滚)。
<script setup lang="ts">
/** 场景:恢复二次确认(ElMessageBox 由业务层调用) */
import { ElMessage, ElMessageBox } from 'element-plus'
import { BizVersionHistory } from 'vue3-ep-biz-lib'
import type { BizVersionItem } from 'vue3-ep-biz-lib'
const versions: BizVersionItem[] = [
{ id: 'v2', version: '流程定义 v2', author: '系统', current: true },
{ id: 'v1', version: '流程定义 v1', author: '系统' },
]
const onRestore = (item: BizVersionItem): void => {
void ElMessageBox.confirm(
`恢复到 ${item.version} 后当前配置将被覆盖,且不可撤销。`,
'恢复确认',
{ type: 'warning', confirmButtonText: '恢复', cancelButtonText: '取消' },
)
.then(() => ElMessage.success(`已恢复到 ${item.version}(模拟)`))
.catch(() => ElMessage.info('已取消'))
}
</script>
<template>
<BizVersionHistory :versions="versions" @restore="onRestore" />
</template>
显示代码
说明插槽
- 推广计划 v2当前版本市场部预算50 万→80 万投放渠道信息流→信息流 + 搜索周期4 周→6 周
- 推广计划 v1市场部预算—→50 万
note 插槽接管说明区(变更字段列表等富展示)。<script setup lang="ts">
/** 场景:note 插槽——变更字段富展示 */
import { BizVersionHistory } from 'vue3-ep-biz-lib'
import type { BizVersionItem } from 'vue3-ep-biz-lib'
interface ChangeEntry {
field: string
from: string
to: string
}
const versions: BizVersionItem[] = [
{ id: 'v2', version: '推广计划 v2', author: '市场部', current: true },
{ id: 'v1', version: '推广计划 v1', author: '市场部' },
]
const changesOf = (id: string): ChangeEntry[] =>
id === 'v2'
? [
{ field: '预算', from: '50 万', to: '80 万' },
{ field: '投放渠道', from: '信息流', to: '信息流 + 搜索' },
{ field: '周期', from: '4 周', to: '6 周' },
]
: [{ field: '预算', from: '—', to: '50 万' }]
</script>
<template>
<BizVersionHistory :versions="versions">
<template #note="{ item }">
<div style="display: flex; flex-direction: column; gap: 3px">
<div v-for="change in changesOf(item.id)" :key="change.field" style="display: flex; gap: 8px; font-size: 12px">
<span style="min-width: 64px; color: var(--el-text-color-secondary)">{{ change.field }}</span>
<span style="color: var(--el-color-danger)">{{ change.from }}</span>
<span style="color: var(--el-text-color-placeholder)">→</span>
<span style="color: var(--el-color-success)">{{ change.to }}</span>
</div>
</div>
</template>
</BizVersionHistory>
</template>
显示代码
操作插槽
- 标书 v3当前版本商务组
- 标书 v2商务组
actions 插槽接管行内操作(下载版本 / 预览等)。<script setup lang="ts">
/** 场景:actions 插槽——下载版本 / 预览 */
import { ElButton, ElMessage } from 'element-plus'
import { BizVersionHistory } from 'vue3-ep-biz-lib'
const versions = [
{ id: 'v3', version: '标书 v3', author: '商务组', current: true },
{ id: 'v2', version: '标书 v2', author: '商务组' },
]
</script>
<template>
<BizVersionHistory :versions="versions">
<template #actions="{ item, onView, onCompare }">
<ElButton link type="primary" size="small" @click="onView?.()">预览</ElButton>
<ElButton link size="small" @click="ElMessage.success(`下载 ${item.version}(模拟)`)">下载</ElButton>
<ElButton link size="small" @click="onCompare?.()">对比</ElButton>
</template>
</BizVersionHistory>
</template>
显示代码
加载与空态
该资产暂无版本记录
loading 与空列表切换。
<script setup lang="ts">
/** 场景:loading 与空态切换 */
import { ref } from 'vue'
import { ElButton } from 'element-plus'
import { BizVersionHistory } from 'vue3-ep-biz-lib'
import type { BizVersionItem } from 'vue3-ep-biz-lib'
const loading = ref(false)
const versions = ref<BizVersionItem[]>([])
const load = (): void => {
loading.value = true
setTimeout(() => {
versions.value = [
{ id: 'v1', version: 'v1.0.0', author: '初始化', current: true },
]
loading.value = false
}, 1000)
}
</script>
<template>
<div>
<div style="margin-bottom: 10px; display: flex; gap: 8px">
<ElButton size="small" :loading="loading" @click="load">加载版本</ElButton>
<ElButton size="small" @click="versions = []">清空</ElButton>
</div>
<BizVersionHistory :versions="versions" :loading="loading" :max-height="240" empty-text="该资产暂无版本记录" />
</div>
</template>
显示代码
角标与作者
- v3.0.0当前版本重大不兼容2026-10-26 18:12架构组 · 王强接口全面升级 v3 废弃 12 个旧接口
- v2.9.0性能2026-10-20 11:12后端组 · 李娜查询链路提速 40%
- v2.8.02026-10-13 15:12前端组 · 张伟
- v2.7.1热修2026-10-05 09:12运维组 · 赵磊
tags 角标(重大 / 性能 / 热修)+ 多作者完整信息展示。<script setup lang="ts">
/** 场景:角标与多作者——tags 数组 + 作者 / 时间完整信息 */
import { ElMessage } from 'element-plus'
import { BizVersionHistory } from 'vue3-ep-biz-lib'
import type { BizVersionItem } from 'vue3-ep-biz-lib'
const dayOf = (offset: number, h: number): string => {
const d = new Date()
d.setDate(d.getDate() - offset)
d.setHours(h, 12, 0, 0)
return d.toISOString()
}
const versions: BizVersionItem[] = [
{ id: 'v5', version: 'v3.0.0', author: '架构组 · 王强', time: dayOf(0, 18), current: true, tags: ['重大', '不兼容'], note: '接口全面升级 v3\n废弃 12 个旧接口' },
{ id: 'v4', version: 'v2.9.0', author: '后端组 · 李娜', time: dayOf(6, 11), tags: ['性能'], note: '查询链路提速 40%' },
{ id: 'v3', version: 'v2.8.0', author: '前端组 · 张伟', time: dayOf(13, 15) },
{ id: 'v2', version: 'v2.7.1', author: '运维组 · 赵磊', time: dayOf(21, 9), tags: ['热修'] },
]
const onView = (item: BizVersionItem): void => {
ElMessage.info(`查看 ${item.version}(${item.author ?? ''})`)
}
</script>
<template>
<BizVersionHistory :versions="versions" :max-height="320" @view="onView" />
</template>
显示代码
长列表与对比状态
- v1.9.0当前版本迭代组
- v1.8.0迭代组
- v1.7.0迭代组
- v1.6.0迭代组
- v1.5.0迭代组
- v1.4.0迭代组
- v1.3.0迭代组
- v1.2.0迭代组
- v1.1.0迭代组
- v1.0.0迭代组
(未查询)
max-height 滚动 + expose getCompareBase / clearCompare 对比基准管理。<script setup lang="ts">
/** 场景:长列表滚动 + clearCompare——getCompareBase 状态查询 */
import { ref } from 'vue'
import { ElButton } from 'element-plus'
import { BizVersionHistory } from 'vue3-ep-biz-lib'
import type { BizVersionHistoryInstance } from 'vue3-ep-biz-lib'
const refEl = ref<BizVersionHistoryInstance | null>(null)
const baseText = ref('(未查询)')
const queryBase = (): void => {
const base = refEl.value?.getCompareBase()
baseText.value = base === null || base === undefined ? '(未选基准)' : `基准:${base.version}`
}
const versions = Array.from({ length: 10 }, (_, i) => ({
id: `h${i}`,
version: `v1.${9 - i}.0`,
author: '迭代组',
current: i === 0,
}))
</script>
<template>
<div>
<BizVersionHistory ref="refEl" :versions="versions" :max-height="200" @compare="() => {}" />
<div style="margin-top: 10px; display: flex; gap: 8px; align-items: center">
<ElButton size="small" @click="queryBase">getCompareBase()</ElButton>
<ElButton size="small" @click="refEl?.clearCompare()">clearCompare()</ElButton>
<span style="font-size: 12px; color: var(--el-text-color-secondary)">{{ baseText }}</span>
</div>
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| versions | BizVersionItem[] | [] | 版本列表(新→旧:version / author / time / note / current / tags) |
| loading | boolean | false | 加载态 |
| show-actions | boolean | true | 行内操作按钮 |
| max-height | number | string | 420 | 最大高度(超出滚动) |
| empty-text | string | '暂无版本记录' | 空态文案 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| view | (item) | 查看版本 |
| restore | (item) | 恢复此版本(业务层确认后执行) |
| compare | (a, b) | 两次点选完成 A/B 对比选择 |
Slots
| 插槽名 | 作用域 | 说明 |
|---|---|---|
| note | { item } | 版本说明区接管 |
| actions | { item, onView, onRestore, onCompare } | 行内操作接管 |
Expose
| 名称 | 类型 | 说明 |
|---|---|---|
| getCompareBase | () => BizVersionItem | null | 当前对比基准(未选为 null) |
| clearCompare | () => void | 清空对比选择 |