Files
property-manager-side/wuye-manager-uniapp/components/stops/stops.vue
2026-05-09 17:10:50 +08:00

177 lines
3.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="steps-vertical">
<view class="step-item" v-for="(item, index) in steps" :key="index">
<!-- 左侧:圆点 + 竖线 -->
<view class="step-left">
<!-- 圆点 -->
<view class="step-circle" :class="getClass(index)">
<!-- 插槽:自定义圆点 -->
<slot v-if="$slots.circle" name="circle" :index="index" :status="getStatus(index)">
</slot>
<view v-else-if="getStatus(index) === 'finish'">
<uni-icons type="checkmarkempty" size="15" :color="props.color"></uni-icons>
</view>
<text v-else-if="getStatus(index) === 'process'">{{ index + 1 }}</text>
<text v-else-if="getStatus(index) === 'wait'">{{ index + 1 }}</text>
</view>
<!-- 竖线(最后一条不显示) -->
<view
class="step-line"
:class="{ finish: getStatus(index) === 'finish' }"
v-if="index < steps.length - 1"
></view>
</view>
<!-- 右侧:内容区域(支持插槽!) -->
<view class="step-right">
<!-- 默认标题 -->
<view
class="step-title"
:class="{ active: getStatus(index) !== 'wait' }"
v-if="!$slots.item"
>
{{ item.title }}
</view>
<!-- 默认描述 -->
<view class="step-desc" v-if="item.desc && !$slots.item">
{{ item.desc }}
</view>
<!-- 🔥 核心:自定义内容插槽 -->
<slot
name="item"
v-if="$slots.item"
:index="index"
:status="getStatus(index)"
:data="item"
></slot>
</view>
</view>
</view>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
// 步骤列表
steps: {
type: Array,
default: () => []
},
// 当前步骤(从 0 开始)
current: {
type: Number,
default: 0
},
// 主题色
color: {
type: String,
default: '#007aff'
}
})
// 获取状态:finish / process / wait
const getStatus = index => {
if (index < props.current) return 'finish'
if (index === props.current) return 'process'
return 'wait'
}
// 样式类
const getClass = index => {
return 'step-circle-' + getStatus(index)
}
</script>
<style scoped lang="scss">
.step-item {
display: flex;
position: relative;
}
/* 左侧 */
.step-left {
display: flex;
flex-direction: column;
align-items: center;
margin-right: 14rpx;
}
/* 圆点 */
.step-circle {
width: 48rpx;
height: 48rpx;
border-radius: 50%;
font-size: 32rpx;
line-height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
z-index: 10;
border: 3rpx solid transparent;
color: #999999;
border-color: #999999;
}
/* 已完成 */
.step-circle-finish {
background: transparent;
color: v-bind('props.color');
border-color: v-bind('props.color');
}
/* 进行中 */
.step-circle-process {
border-color: v-bind('props.color');
color: #fff;
background: v-bind('props.color');
}
/* 待完成 */
.step-circle-wait {
color: #999999;
border-color: #999999;
}
/* 竖线 */
.step-line {
width: 4rpx;
height: 100%;
background: #e5e5e5;
margin-top: 8rpx;
margin-bottom: 8rpx;
}
.step-line.finish {
background: v-bind('props.color');
}
/* 右侧内容 */
.step-right {
flex: 1;
}
.step-title {
font-size: 28rpx;
color: #666;
line-height: 1.4;
}
.step-title.active {
color: #333;
font-weight: 500;
}
.step-desc {
font-size: 24rpx;
color: #999;
margin-top: 8rpx;
line-height: 1.5;
}
</style>