步骤条组件新增direction和activeColor属性,增加了竖的步骤条 (#49)

This commit is contained in:
张敏 2017-07-04 19:06:04 +08:00 committed by GitHub
parent 2584fb8b04
commit 2c47a3443b
5 changed files with 213 additions and 82 deletions

View File

@ -111,6 +111,29 @@ export default {
``` ```
::: :::
#### 竖式步骤条
可以通过设置`direction`属性来改变步骤条的显示方式,可选值有`vertical/horizontal`
:::demo 只显示步骤条
```html
<van-steps direction="vertical" :active="0" active-color="#f60">
<van-step>
<h3>【城市】最新的物流状态之类的表述哈哈哈哈</h3>
<p>2016-07-12 12:12:12</p>
</van-step>
<van-step>
<h3>【城市】已经过了的物流状态我是折行我是折行我是折行联系电话158630099999</h3>
<p>2016-07-12 12:12:12</p>
</van-step>
<van-step>
<h3>未发货</h3>
<p>2016-07-12 12:12:12</p>
</van-step>
</van-steps>
```
:::
### 高级用法 ### 高级用法
可以使用具名`slot`增加自定义内容,其中包含`icon``message-extra` 可以使用具名`slot`增加自定义内容,其中包含`icon``message-extra`
@ -137,6 +160,8 @@ export default {
| iconClass | 当前步骤栏为icon添加的类 | `string` | | | | iconClass | 当前步骤栏为icon添加的类 | `string` | | |
| title | 当前步骤从标题 | `string` | | | | title | 当前步骤从标题 | `string` | | |
| description | 当前步骤描述 | `string` | | | | description | 当前步骤描述 | `string` | | |
| direction | 显示方向 | `string` | `horizontal` | `vertical/horizontal` |
| activeColor | `active`状态时的颜色 | `string` | `#06bf04` | |
### Steps Slot ### Steps Slot

View File

@ -1,12 +1,12 @@
<template> <template>
<div class="van-step" :class="statusClass"> <div class="van-step" :class="stepClass">
<div class="van-step__circle-container"> <div class="van-step__circle-container">
<i class="van-step__circle" v-if="status !== 'process'"></i> <i class="van-step__circle" v-if="status !== 'process'"></i>
<i class="van-icon van-icon-checked" v-else></i> <i class="van-icon van-icon-checked" :style="{ color: $parent.activeColor }" v-else></i>
</div> </div>
<p class="van-step__title"> <div class="van-step__title" :style="titleStyle">
<slot></slot> <slot></slot>
</p> </div>
<div class="van-step__line"></div> <div class="van-step__line"></div>
</div> </div>
</template> </template>
@ -30,9 +30,18 @@ export default {
return 'process'; return 'process';
} }
}, },
statusClass() { stepClass() {
const status = this.status; const status = this.status;
return status ? 'van-step--' + status : ''; const statusClass = status ? 'van-step--' + status : '';
const directionClass = `van-step--${this.$parent.direction}`;
return [directionClass, statusClass];
},
titleStyle() {
if (this.status === 'process') {
return {
color: this.$parent.activeColor
};
}
} }
} }
}; };

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="van-steps" :class="`van-steps--${steps.length}`"> <div class="van-steps" :class="stepsClass">
<div class="van-steps__status" v-if="title || description"> <div class="van-steps__status" v-if="title || description">
<div class="van-steps__icon" v-if="icon || $slots.icon"> <div class="van-steps__icon" v-if="icon || $slots.icon">
<slot name="icon"> <slot name="icon">
@ -41,13 +41,31 @@ export default {
default: '' default: ''
}, },
title: String, title: String,
description: String description: String,
direction: {
type: String,
default: 'horizontal'
},
activeColor: {
type: String,
default: '#06bf04'
}
}, },
data() { data() {
return { return {
steps: [] steps: []
}; };
},
computed: {
stepsClass() {
const direction = this.direction;
const lengthClass = `van-steps--${this.steps.length}`;
const directionClass = `van-steps--${direction}`;
return direction === 'horizontal' ? [lengthClass, directionClass] : [directionClass];
}
} }
}; };
</script> </script>

View File

@ -1,13 +1,32 @@
@import './common/var.css'; @import './common/var.css';
@import './mixins/ellipsis.css'; @import './mixins/ellipsis.css';
@import './icon.css'; @import './icon.css';
@import './mixins/border_retina.css';
@component-namespace van { @component-namespace van {
@b steps { @b steps {
overflow: hidden; overflow: hidden;
padding: 0 10px;
background-color: #fff; background-color: #fff;
@m horizontal {
padding: 0 10px;
.van-steps__items {
margin: 0 0 10px;
overflow: hidden;
position: relative;
padding-bottom: 22px;
&.van-steps__items--alone {
padding-top: 10px;
}
}
}
@m vertical {
padding: 0 0 0 35px;
}
@m 4 { @m 4 {
.van-step { .van-step {
width: 33.2%; width: 33.2%;
@ -53,86 +72,94 @@
max-height: 18px; max-height: 18px;
@mixin multi-ellipsis 1; @mixin multi-ellipsis 1;
} }
@e items {
margin: 0 0 10px;
overflow: hidden;
position: relative;
padding-bottom: 20px;
@m alone {
padding-top: 10px;
}
}
} }
@b step { @b step {
font-size: 14px; font-size: 14px;
float: left;
position: relative; position: relative;
color: $c-gray-dark; color: $c-gray-dark;
@m horizontal {
float: left;
@m finish { &:first-child {
color: $c-black; .van-step__title {
transform: none;
.van-step__circle, margin-left: 0;
.van-step__line { }
background-color: $c-green;
} }
}
@m process { &:last-child {
color: $c-black; position: absolute;
right: 10px;
width: auto;
.van-step__title {
transform: none;
margin-left: 0;
}
.van-step__circle-container {
left: auto;
right: -9px;
}
.van-step__line {
width: 0;
}
}
.van-step__circle-container { .van-step__circle-container {
top: 24px; position: absolute;
top: 28px;
left: -8px;
padding: 0 8px;
background-color: #fff;
z-index: 1;
} }
.van-icon { .van-step__title {
font-size: 12px; font-size: 12px;
color: $c-green; transform: translate3d(-50%, 0, 0);
line-height: 1; display: inline-block;
display: block; margin-left: 3px;
}
}
&:first-child {
.van-step__title {
transform: none;
margin-left: 0;
}
}
&:last-child {
position: absolute;
right: 10px;
width: auto;
.van-step__title {
transform: none;
margin-left: 0;
}
.van-step__circle-container {
left: auto;
right: -9px;
} }
.van-step__line { .van-step__line {
width: 0; position: absolute;
left: 0px;
top: 30px;
width: 100%;
height: 1px;
background-color: $c-gray-light;
}
&.van-step--finish {
color: $c-black;
.van-step__circle,
.van-step__line {
background-color: $c-green;
}
}
&.van-step--process {
color: $c-black;
.van-step__circle-container {
top: 24px;
}
.van-icon {
font-size: 12px;
color: $c-green;
line-height: 1;
display: block;
}
} }
} }
.van-step__circle-container { .van-step__circle {
position: absolute;
top: 28px;
left: -8px;
padding: 0 8px;
background-color: #fff;
z-index: 1;
}
@e circle {
display: block; display: block;
width: 5px; width: 5px;
height: 5px; height: 5px;
@ -140,20 +167,59 @@
border-radius: 50%; border-radius: 50%;
} }
@e title { @m vertical {
font-size: 12px; float: none;
transform: translate3d(-50%, 0, 0); display: block;
display: inline-block; font-size: 14px;
margin-left: 3px; line-height: 18px;
} padding: 10px 10px 10px 0;
@e line { &::after {
position: absolute; @mixin border-retina (bottom);
left: 0px; }
top: 30px;
width: 100%; &:first-child {
height: 1px; &::before {
background-color: $c-gray-light; content: '';
position: absolute;
width: 1px;
height: 20px;
background-color: #fff;
top: 0;
left: -15px;
z-index: 1;
}
}
&:last-child::after {
display: none;
}
.van-step__circle-container > i {
position: absolute;
z-index: 2;
}
.van-icon-checked {
top: 12px;
left: -20px;
line-height: 1;
font-size: 12px;
}
.van-step__circle {
top: 16px;
left: -17px;
}
.van-step__line {
position: absolute;
top: 0;
left: -15px;
width: 1px;
height: 100%;
background-color: $c-gray-light;
}
} }
} }
} }

View File

@ -21,8 +21,21 @@ describe('Steps', () => {
const finishStep = wrapper.find('.van-step')[0]; const finishStep = wrapper.find('.van-step')[0];
expect(finishStep.hasClass('van-step--finish')).to.be.true; expect(finishStep.hasClass('van-step--finish')).to.be.true;
expect(finishStep.hasClass('van-step--horizontal')).to.be.true;
const proccessStep = wrapper.find('.van-step')[1]; const proccessStep = wrapper.find('.van-step')[1];
expect(proccessStep.hasClass('van-step--process')).to.be.true; expect(proccessStep.hasClass('van-step--process')).to.be.true;
}); });
it('create a vertical step', () => {
wrapper = mount(Steps, {
propsData: {
direction: 'vertical'
}
});
expect(wrapper.hasClass('van-steps')).to.be.true;
expect(wrapper.hasClass('van-steps--vertical')).to.be.true;
expect(wrapper.data().steps.length).to.equal(0);
});
}); });