51 lines
1.7 KiB
Plaintext
51 lines
1.7 KiB
Plaintext
<template>
|
|
<!-- 时间线 / 步骤条:内部统一由组件库 xSteps 渲染(vertical 模式) -->
|
|
<x-steps :model-value="activeIndex" vertical :icon-size="'40rpx'" :label-size="'27rpx'" :desc-size="'24rpx'"
|
|
color="#9CA3AF" active-color="#2563EB">
|
|
<x-steps-item v-for="(node, i) in nodes" :key="i" :label="node.title" :desc="descOf(node)"
|
|
:icon="iconOf(node)" :active-icon="activeIconOf(node)" :active-color="colorOf(node)"></x-steps-item>
|
|
</x-steps>
|
|
</template>
|
|
|
|
<script lang="uts" setup>
|
|
import { PropType, computed } from 'vue'
|
|
import { HrTimelineNode } from '@/mock/types.uts'
|
|
|
|
/**
|
|
* 时间线
|
|
* 设计稿的时间线 = 纵向步骤条,这里直接交给 xSteps(vertical)渲染,
|
|
* 用每项的 icon / activeIcon / activeColor 表达 normal / ok / warn 三种语义色。
|
|
*/
|
|
const props = defineProps({
|
|
nodes : {
|
|
type : Array as PropType<HrTimelineNode[]>,
|
|
default : () : HrTimelineNode[] => [] as HrTimelineNode[]
|
|
}
|
|
})
|
|
|
|
/** 全部节点都视为「已发生」 */
|
|
const activeIndex = computed(() : number => {
|
|
return props.nodes.length == 0 ? 0 : props.nodes.length - 1
|
|
})
|
|
|
|
function descOf(node : HrTimelineNode) : string {
|
|
return node.sub == '' ? node.time : `${node.time} · ${node.sub}`
|
|
}
|
|
|
|
function iconOf(node : HrTimelineNode) : string {
|
|
return 'checkbox-blank-circle-line'
|
|
}
|
|
|
|
function activeIconOf(node : HrTimelineNode) : string {
|
|
if (node.theme == 'ok') { return 'checkbox-circle-fill' }
|
|
if (node.theme == 'warn') { return 'error-warning-fill' }
|
|
return 'checkbox-blank-circle-fill'
|
|
}
|
|
|
|
function colorOf(node : HrTimelineNode) : string {
|
|
if (node.theme == 'ok') { return '#10B981' }
|
|
if (node.theme == 'warn') { return '#DC2626' }
|
|
return '#2563EB'
|
|
}
|
|
</script>
|