合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
步骤条(steps)组件常用于描述一件事情从起始到结束的过程,电商购物物流场景使用居多。步骤条一般具有如下特点:
效果图如下:
|
|
基本布局代码如下:
<template>
<div class="container">
<text class="section">横向排列</text>
<steps class="stepcss" options="{{list2}}" active-color="#007AFF" active="{{active}}" direction="row"></steps>
<text class="section">纵向排列</text>
<steps if="{{isShow}}}" class="stepcss" options="{{list2}}" active-color="#007AFF" active="{{active}}" direction="column"></steps>
</div>
</template>
步骤条整体外观都是通用的,但是内部具体的样式有区别,在设计的时候,不能把内部样式固定,否则一旦步骤条的UI有变化,会导致子组件也要修改,违背了对外开源的初衷。
所以,在子组件steps.ux中,开放多种样式属性,方便开发者自定义样式。
<template>
<div class="rootcontainer">
<block if="{{direction=='column'}}">
<div style="width: 100%;">
<!--垂直分割线 -->
<div style="flex-direction: column; align-items: center; padding-top: 16px; width: 60px;">
<div if="{{computed}}" class="steps_column-line-item" for="{{listoptions}}">
<image if="$idx==active" class="steps_column-imgcheck"></image>
<image else class="steps_column-imgcircle"></image>
<div if="$idx!=options.length-1 && computed" class="steps_column-line" style="height: {{$item.lineHeight}}px;"></div>
<!-- <div if="$idx!=options.length-1 && computed" class="steps_column-line" style="height:100%;"></div> -->
</div>
</div>
<!--垂直事件描述-->
<div style="flex-direction: column; width: 100%;">
<block for="{{listoptions}}">
<div if="$idx==active" class="steps_column_text_div" id="{{$item.itemId}}">
<text class="steps_txt_state" style="color:{{activeColor}};">{{ $item.title }}</text>
<text class="steps_txt_des" style="color:{{activeColor}};">{{ $item.desc }}</text>
<text class="steps_txt_time" style="color:{{activeColor}};">{{ $item.time }}</text>
<text class="steps_row-line"></text>
</div>
<div else class="steps_column_text_div" id="{{$item.itemId}}">
<text class="steps_txt_state" style="color:{{deactiveColor}};">{{ $item.title }}</text>
<text class="steps_txt_des" style="color:{{deactiveColor}};">{{ $item.desc }}</text>
<text class="steps_txt_time" style="color:{{deactiveColor}};">{{ $item.time }}</text>
<text class="steps_row-line"></text>
</div>
</block>
</div>
</div>
</block>
<block else>
<!--水平方向事件 -->
<div id="rowroot" style="flex-direction: column;width: 100%;">
<!--事件文字布局 -->
<div class="steps_row">
<div class="steps_row_text_div" style="width: {{row_list_item_width}}px;" id="{{$item.itemId}}" for="{{listoptions}}">
<block if="$idx==active">
<text class="steps_txt_state" style="color:{{activeColor}};">{{ $item.title }}</text>
<text class="steps_txt_des" style="color:{{activeColor}};">{{ $item.desc }}</text>
<text class="steps_txt_time" style="color:{{activeColor}};">{{ $item.time }}</text>
</block>
<block else>
<text class="steps_txt_state" style="color:{{deactiveColor}};">{{ $item.title }}</text>
<text class="steps_txt_des" style="color:{{deactiveColor}};">{{ $item.desc }}</text>
<text class="steps_txt_time" style="color:{{deactiveColor}};">{{ $item.time }}</text>
</block>
</div>
</div>
<!--分割线布局 -->
<div class="steps_row_line_root" style=" margin-left: {{lineleft}}px; margin-right:{{lineleft}}px;" >
<div if="{{computed}}" class="steps_row-line-item" for="{{listoptions}}">
<image if="$idx==active" class="steps_column-imgcheck"></image>
<image else class="steps_column-imgcircle"></image>
<block if="$idx!=options.length-1">
<div class="steps_column-line" style="width:{{row_list_item_width+5}}px; height: 1px;"></div>
</block>
</div>
</div>
</div>
</block>
</div>
</template> 属性 |
类型 |
默认值 |
描述 |
|---|---|---|---|
direction |
String |
column |
步骤排列方向。 |
options |
Array |
- |
事件源。 |
active |
Number |
0 |
当前步骤。 |
activeColor |
Color |
#1aad19 |
激活状态的颜色。 |
deactiveColor |
Color |
#999999 |
未激活状态的颜色。 |
支持的事件:
无
calRowItemWidth(len) {
var that = this;
this.$element('rowroot').getBoundingClientRect({
success: function (data) {
console.log('calRowItemWidth getBoundingClientRect succeeded, result data ='
+ JSON.stringify(data));
that.row_list_item_width = data.width / len ;
that.lineleft = that.row_list_item_width / 2 ;
console.info("calRowItemWidth= " + that.row_list_item_width);
that.computed = true;
},
fail() {
console.log('getBoundingClientRect failed');
},
complete: function () {
console.log('getBoundingClientRect completed');
}
});
} calLineHeight(optionItem) {
var that = this;
this.$element(optionItem.itemId).getBoundingClientRect({
success: function (data) {
console.log('getBoundingClientRect succeeded, result data ='
+ JSON.stringify(data));
let lineHeight = data.height - 10;
optionItem.lineHeight = lineHeight;
that.computed = true;
},
fail() {
console.log('getBoundingClientRect failed');
},
complete: function () {
console.log('getBoundingClientRect completed');
}
});
},
getBoundingClientRect( )方法只能在页面渲染后才可以计算出组件的宽高值,在页面生命周期调用时,一般要延时200ms左右。
步骤条每个事件源高度和事件轴高度是根据自身内容来动态适配的,没有将高度固定。由于轴线高度、宽度值计算受限于渲染后,当计算出结果时,界面刷新,可能会出现界面闪一下的效果。
如果您的每个事件源内容少,建议固定高度,省去一些计算步骤。
步骤条组件steps.ux代码:
<template>
<div class="rootcontainer">
<block if="{{direction=='column'}}">
<div style="width: 100%;">
<!--垂直分割线 -->
<div style="flex-direction: column; align-items: center; padding-top: 16px; width: 60px;">
<div if="{{computed}}" class="steps_column-line-item" for="{{listoptions}}">
<image if="$idx==active" class="steps_column-imgcheck"></image>
<image else class="steps_column-imgcircle"></image>
<div if="$idx!=options.length-1 && computed" class="steps_column-line" style="height: {{$item.lineHeight}}px;"></div>
<!-- <div if="$idx!=options.length-1 && computed" class="steps_column-line" style="height:100%;"></div> -->
</div>
</div>
<!--垂直事件描述-->
<div style="flex-direction: column; width: 100%;">
<block for="{{listoptions}}">
<div if="$idx==active" class="steps_column_text_div" id="{{$item.itemId}}">
<text class="steps_txt_state" style="color:{{activeColor}};">{{ $item.title }}</text>
<text class="steps_txt_des" style="color:{{activeColor}};">{{ $item.desc }}</text>
<text class="steps_txt_time" style="color:{{activeColor}};">{{ $item.time }}</text>
<text class="steps_row-line"></text>
</div>
<div else class="steps_column_text_div" id="{{$item.itemId}}">
<text class="steps_txt_state" style="color:{{deactiveColor}};">{{ $item.title }}</text>
<text class="steps_txt_des" style="color:{{deactiveColor}};">{{ $item.desc }}</text>
<text class="steps_txt_time" style="color:{{deactiveColor}};">{{ $item.time }}</text>
<text class="steps_row-line"></text>
</div>
</block>
</div>
</div>
</block>
<block else>
<!--水平方向事件 -->
<div id="rowroot" style="flex-direction: column;width: 100%;">
<!--事件文字布局 -->
<div class="steps_row">
<div class="steps_row_text_div" style="width: {{row_list_item_width}}px;" id="{{$item.itemId}}" for="{{listoptions}}">
<block if="$idx==active">
<text class="steps_txt_state" style="color:{{activeColor}};">{{ $item.title }}</text>
<text class="steps_txt_des" style="color:{{activeColor}};">{{ $item.desc }}</text>
<text class="steps_txt_time" style="color:{{activeColor}};">{{ $item.time }}</text>
</block>
<block else>
<text class="steps_txt_state" style="color:{{deactiveColor}};">{{ $item.title }}</text>
<text class="steps_txt_des" style="color:{{deactiveColor}};">{{ $item.desc }}</text>
<text class="steps_txt_time" style="color:{{deactiveColor}};">{{ $item.time }}</text>
</block>
</div>
</div>
<!--分割线布局 -->
<div class="steps_row_line_root" style=" margin-left: {{lineleft}}px; margin-right:{{lineleft}}px;" >
<div if="{{computed}}" class="steps_row-line-item" for="{{listoptions}}">
<image if="$idx==active" class="steps_column-imgcheck"></image>
<image else class="steps_column-imgcircle"></image>
<block if="$idx!=options.length-1">
<div class="steps_column-line" style="width:{{row_list_item_width+5}}px; height: 1px;"></div>
</block>
</div>
</div>
</div>
</block>
</div>
</template>
<style>
.rootcontainer {
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
}
.steps_column {
display: flex;
flex-direction: row;
justify-content: center;
padding-top: 16px;
}
.steps_column-line-item {
flex-direction: column;
align-items: center;
justify-content: center;
}
.steps_column_text_div {
flex-direction: column;
align-items: flex-start;
width: 100%;
padding-top: 16px;
padding-left: 30px;
}
.steps_row-line {
height: 1px;
width: 100%;
margin-top: 20px;
background-color: #999;
}
.steps_column-line {
width: 1px;
background-color: #999;
}
.steps_row-circle {
width: 10px;
height: 10px;
border-radius: 1px;
background-color: #999;
}
.steps_column-imgcircle {
width: 10px;
height: 10px;
border-radius: 5px;
background-color: #999;
}
.steps_column-imgcheck {
width: 30px;
height: 30px;
border-radius: 15px;
background-color: #00bfff;
}
.steps_txt_state {
font-size: 30px;
font-weight: bold;
}
.steps_txt_des {
font-size: 25px;
margin-top: 6px;
}
.steps_txt_time {
font-size: 25px;
margin-top: 6px;
}
.steps_row {
display: flex;
flex-direction: row;
justify-content: center;
}
.steps_row_text_div {
flex-direction: column;
align-items: center;
justify-content: flex-end;
width: 100%;
}
.steps_row-line-item {
flex-direction: row;
align-items: center;
justify-content: center;
}
.steps_row_line_root {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
</style>
<script>
module.exports = {
props: {
direction: {
// 排列方向 row column
type: String,
default: 'column'
},
activeColor: {
// 激活状态颜色
type: String,
default: '#1aad19'
},
deactiveColor: {
// 未激活状态颜色
type: String,
default: '#999999'
},
active: {
// 当前步骤
type: Number,
default: 0
},
options: {
type: Array,
default() {
return []
}
}
},
data() {
return {
txtColor: '#1aad19',
listoptions: [],
lineoptions: [],
row_list_item_width: 200,
lineleft: 0,
computed: false
}
},
onInit() {
this.initListOptions();
setTimeout(() => {
this.cal();
}, 200);
},
initListOptions() {
let len = this.options.length;
for (var i = 0; i < len; i++) {
let item = {};
item.desc = this.options[i].desc;
item.title = this.options[i].title;
item.time = this.options[i].time;
item.itemId = "item" + i;
item.lineHeight = 0;
this.listoptions.push(item);
}
},
cal() {
let len = this.listoptions.length;
if (this.direction == "column") {
for (var i = 0; i < len; i++) {
let optionItem = this.listoptions[i];
this.calLineHeight(optionItem);
}
} else {
this.calRowItemWidth(len);
}
},
calLineHeight(optionItem) {
var that = this;
this.$element(optionItem.itemId).getBoundingClientRect({
success: function (data) {
console.log('getBoundingClientRect succeeded, result data ='
+ JSON.stringify(data));
let lineHeight = data.height - 10;
optionItem.lineHeight = lineHeight;
that.computed = true;
},
fail() {
console.log('getBoundingClientRect failed');
},
complete: function () {
console.log('getBoundingClientRect completed');
}
});
},
calRowItemWidth(len) {
var that = this;
this.$element('rowroot').getBoundingClientRect({
success: function (data) {
console.log('calRowItemWidth getBoundingClientRect succeeded, result data ='
+ JSON.stringify(data));
that.row_list_item_width = data.width / len;
that.lineleft = that.row_list_item_width / 2;
console.info("calRowItemWidth= " + that.row_list_item_width);
that.computed = true;
},
fail() {
console.log('getBoundingClientRect failed');
},
complete: function () {
console.log('getBoundingClientRect completed');
}
});
}
}
</script>
页面hello.ux代码:
<import name="steps" src="../Steps/steps.ux"></import>
<template>
<div class="container">
<text class="section">横向排列</text>
<steps class="stepcss" options="{{list2}}" active-color="#007AFF" active="{{active}}" direction="row"></steps>
<text class="section">纵向排列</text>
<steps if="{{isShow}}}" class="stepcss" options="{{list2}}" active-color="#007AFF" active="{{active}}" direction="column"></steps>
</div>
</template>
<style>
.container {
flex-direction: column;
align-items: center;
padding-left: 20px;
padding-right: 20px;
padding-top: 16px;
}
.section {
background-color: #00bfff;
width: 100%;
height: 80px;
margin-top: 25px;
}
.stepcss {
padding-left: 30px;
padding-right: 30px;
width: 100%;
}
</style>
<script>
module.exports = {
data() {
return {
isShow: true,
active: 1,
list1: [{
title: '事件一',
desc: '2020-11-11'
}, {
title: '事件二',
desc: '2020-11-12'
}, {
title: '事件二',
desc: '2020-11-12'
},
{
title: '事件3',
desc: '2020-11-12'
},
{
title: '事件4',
desc: '2020-11-12'
},
{
title: '事件5',
desc: '2020-11-12'
}, {
title: '事件6',
desc: '2020-11-12'
}],
list11: [{
title: '事件一',
desc: '2020-11-11'
}, {
title: '事件二',
desc: '2020-11-12'
}, {
title: '事件二',
desc: '2020-11-12'
},
{
title: '事件3',
desc: '2020-11-12'
},
{
title: '事件4',
desc: '2020-11-12'
}],
list2: [{
title: '买家下单',
desc: '待打包',
time: '2020-11-11'
}, {
title: '卖家发货',
desc: '待快递上门取货',
time: '2020-11-12'
}, {
title: '运输中',
desc: '快件已到达深圳',
time: '2020-11-13'
},
{
title: '派件中',
desc: '【深圳市】【福田华强】业务员王明正在派件中。小哥体温今日正常,将佩戴口罩为您投递,也可以联系小哥将您的快递放到指定代收点,祝您身体健康!',
time: '2020-11-14'
}, {
title: '已签收',
desc: '签收人:本人。如有疑问,请联系132xxxxxx。您的快递已经妥投,如果您对我们的服务感到满意,请给个五星好评,鼓励一下我们!您的快递已经妥投,如果您对我们的服务感到满意,请给个五星好评,鼓励一下我们!',
time: '2020-11-14 17:00'
}
]
}
},
onInit() {
console.info("hello onInit ");
this.$page.setTitleBar({
text: 'steps',
textColor: '#ffffff',
backgroundColor: '#007DFF',
backgroundOpacity: 0.5,
menu: true
});
},
onShow(options) {
console.info("hello onShow ");
},
deal: function () {
this.isShow = !this.isShow;
console.info(" this.isShow=" + this.isShow);
}
}
</script>