一、前言
- 由于原生steps组件及各组件库无法满足需求,自行封装多场景适配步骤条。
- 相关知识点:
js修改css变量(行内方案)
、动态样式类名
、作用域插槽及传值
、父子传值
二、注意事项
- 自定义内容插槽与默认样式不能共存
- 考虑到手机屏幕宽度用户体验,
行模式时为一行两个步骤--换行显示
,web端扩展使用时注意替换标签、css单位及行显示样式
- 如
业务需求特殊修改步骤条样式
如当前步骤数字或默认及成功icon等,可对前后伪元素做微调
- 使用时注意各属性有效值
三、代码注释详解
slotFlag
控制插槽自定义内容或组件默认样式,有效值true false
,true为使用插槽;
content插槽
控制内容,传值当前index对标父组件插槽
内容使用;
direction
动态样式控制排列方式,默认值column,有效值row
、row-reverse
、column
、column-reverse
,对应第一步到最后一步的顺序:左-右、右-左、上-下、下-上;
currentStep
控制选中项,默认0,有效值为阿拉伯数字或字符串类型的数字;
--steps_aitive_color
CSS变量控制选中项颜色主题;
activeColor
控制控制选中项颜色值,默认#a41f24,有效值为颜色值;
clickSteps事件
传递点击下标,通过父组件回传可动态变更选中项。
子组件内容
<template>
<!--slotFlag控制插槽自定义内容或组件默认样式-->
<!--content插槽控制内容,传值当前index对标父组件插槽内容使用-->
<template v-if="slotFlag">
<view
:style="{'flex-direction': direction,'--steps_aitive_color': activeColor}"
:class="['steps',{'steps_row':direction==='row'||direction==='row-reverse'}]">
<view
:class="['steps_item',{'steps_item_active':index==currentStep}]"
v-for="(item,index) in stepsList"
:key="item.id"
@click="clickSteps(index)">
<slot name="content" :index="index"></slot>
</view>
</view>
</template>
<!--direction动态样式控制排列方式-->
<!-- steps_row控制行排列时的样式-->
<!-- --steps_aitive_color控制选中颜色主题-->
<!--activeColor控制颜色值-->
<template v-else>
<view
:style="{'flex-direction': direction,'--steps_aitive_color': activeColor}"
:class="['steps',{'steps_row':direction==='row'||direction==='row-reverse'}]">
<!--steps_item_active当前选中的样式类名-->
<!--currentStep控制选择项-->
<view
:class="['steps_item',{'steps_item_active':index==currentStep}]"
v-for="(item,index) in stepsList"
:key="item.id"
@click="clickSteps(index)">
<view class="steps_item_data">{{ item.title }}</view>
<view class="steps_item_data">{{ item.date }}</view>
<view class="steps_item_data" v-if="item.desc">
<view>反馈内容:</view>
{{ item.desc }}
</view>
<view class="steps_item_data" v-if="item.attachment">
<image v-for="(ele,i) in item.attachment" :src="ele" :key="i"></image>
</view>
</view>
</view>
</template>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
// 传递点击事件
const emit = defineEmits(['clickSteps']);
// 解构属性
const {
stepsList,
currentStep,
activeColor,
direction,
slotFlag
} = defineProps({
// 进度总数组
stepsList: {
type: Array,
default: []
},
// 当前进行项
currentStep: {
type: Number || String,
default: 0
},
// 当前进行项颜色
activeColor: {
type: String,
default: '#a41f24'
},
// 排列方式
// 有效值:row、row-reverse、column、column-reverse
direction: {
type: String,
default: 'column'
},
// 是否使用插槽
slotFlag: {
type: Boolean,
default: false
}
});
// 点击某项进度
function clickSteps(i) {
emit('clickSteps', i);
}
</script>
<style lang="scss" scoped>
//css变量控制选中主题色
page {--steps_aitive_color: #a41f24;}
.steps {padding: 20rpx 80rpx 0;display: flex;flex-direction: row;color: #8f939c;
.steps_item {border-bottom: 2rpx solid #cccccc;position: relative;padding: 10rpx 0;
&:before,
&:after {content: '';position: absolute;background-color: #8f939c;}
&:before {left: -46rpx;top: 0;width: 12rpx;height: 12rpx;border-radius: 50%;}
&:after {left: -40rpx;top: 18rpx;width: 2rpx;height: calc(100% - 24rpx);}
}
.steps_item_active {color: var(--steps_aitive_color);border-color: var(--steps_aitive_color) !important;
&:before,
&:after {background-color: var(--steps_aitive_color);}
}
.steps_item_data {margin-bottom: 10rpx;
image {width: 200rpx;height: 200rpx;margin: 0 40rpx 10rpx 0;}
}
}
.steps_row {flex-wrap: wrap;padding: 20rpx;
.steps_item {width: 40%;margin: 0 5%;border-bottom:0;border-top: 2rpx solid #cccccc;
&:after {display: none;}
&:before {top: -6rpx;}
}
}
</style>
父组件使用
步骤条默认数组数据结构示例
- 默认使用时数组中
id、title、date
为必须存在的属性
[{
id: '1q2w3e',
title: '测试标题',
date: '2024-08-08 08:08:08',
desc: '测试内容',
attachment: ['附件url,仅示例', '附件url,仅示例', '附件url,仅示例']
},{
id:'azxcv',
title: '测试标题',
date: '2024-08-08 08:08:08',
desc: '测试内容',
attachment: ['附件url,仅示例', '附件url,仅示例', '附件url,仅示例']
}]
默认使用场景
<U-Steps v-if="detailFeedback.length>0" :stepsList="detailFeedback"
:currentStep="currentStep" @clickSteps="clickSteps">
</U-Steps>
插槽使用
<U-Steps v-if="detailFeedback.length>0"
:stepsList="detailFeedback"
:currentStep="currentStep"
activeColor="blue"
direction="row"
slotFlag
@clickSteps="clickSteps">
<template #content="{index}">
<view>{{ detailFeedback[index].title }}</view>
<view>{{ detailFeedback[index].date }}</view>
</template>
</U-Steps>
四、效果展示
竖向

横向

自定义内容