123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- <template>
- <div
- class="el-step"
- :style="style"
- :class="[
- !isSimple && `is-${$parent.direction}`,
- isSimple && 'is-simple',
- isLast && !space && !isCenter && 'is-flex',
- isCenter && !isVertical && !isSimple && 'is-center'
- ]">
- <!-- icon & line -->
- <div
- class="el-step__head"
- :class="`is-${currentStatus}`">
- <div
- class="el-step__line"
- :style="isLast ? '' : { marginRight: $parent.stepOffset + 'px' }"
- >
- <i class="el-step__line-inner" :style="lineStyle"></i>
- </div>
- <div class="el-step__icon" :class="`is-${icon ? 'icon' : 'text'}`">
- <slot
- v-if="currentStatus !== 'success' && currentStatus !== 'error'"
- name="icon">
- <i v-if="icon" class="el-step__icon-inner" :class="[icon]"></i>
- <div class="el-step__icon-inner" v-if="!icon && !isSimple">{{ index + 1 }}</div>
- </slot>
- <i
- v-else
- :class="['el-icon-' + (currentStatus === 'success' ? 'check' : 'close')]"
- class="el-step__icon-inner is-status"
- >
- </i>
- </div>
- </div>
- <!-- title & description -->
- <div class="el-step__main">
- <div
- class="el-step__title"
- ref="title"
- :class="['is-' + currentStatus]">
- <slot name="title">{{ title }}</slot>
- </div>
- <div v-if="isSimple" class="el-step__arrow"></div>
- <div
- v-else
- class="el-step__description"
- :class="['is-' + currentStatus]">
- <slot name="description">{{ description }}</slot>
- </div>
- </div>
- </div>
- </template>
- <script>
- export default {
- name: 'ElStep',
- props: {
- title: String,
- icon: String,
- description: String,
- status: String
- },
- data() {
- return {
- index: -1,
- lineStyle: {},
- internalStatus: ''
- };
- },
- beforeCreate() {
- this.$parent.steps.push(this);
- },
- beforeDestroy() {
- const steps = this.$parent.steps;
- const index = steps.indexOf(this);
- if (index >= 0) {
- steps.splice(index, 1);
- }
- },
- computed: {
- currentStatus() {
- return this.status || this.internalStatus;
- },
- prevStatus() {
- const prevStep = this.$parent.steps[this.index - 1];
- return prevStep ? prevStep.currentStatus : 'wait';
- },
- isCenter() {
- return this.$parent.alignCenter;
- },
- isVertical() {
- return this.$parent.direction === 'vertical';
- },
- isSimple() {
- return this.$parent.simple;
- },
- isLast() {
- const parent = this.$parent;
- return parent.steps[parent.steps.length - 1] === this;
- },
- stepsCount() {
- return this.$parent.steps.length;
- },
- space() {
- const { isSimple, $parent: { space } } = this;
- return isSimple ? '' : space ;
- },
- style: function() {
- const style = {};
- const parent = this.$parent;
- const len = parent.steps.length;
- const space = (typeof this.space === 'number'
- ? this.space + 'px'
- : this.space
- ? this.space
- : 100 / (len - (this.isCenter ? 0 : 1)) + '%');
- style.flexBasis = space;
- if (this.isVertical) return style;
- if (this.isLast) {
- style.maxWidth = 100 / this.stepsCount + '%';
- } else {
- style.marginRight = -this.$parent.stepOffset + 'px';
- }
- return style;
- }
- },
- methods: {
- updateStatus(val) {
- const prevChild = this.$parent.$children[this.index - 1];
- if (val > this.index) {
- this.internalStatus = this.$parent.finishStatus;
- } else if (val === this.index && this.prevStatus !== 'error') {
- this.internalStatus = this.$parent.processStatus;
- } else {
- this.internalStatus = 'wait';
- }
- if (prevChild) prevChild.calcProgress(this.internalStatus);
- },
- calcProgress(status) {
- let step = 100;
- const style = {};
- style.transitionDelay = 150 * this.index + 'ms';
- if (status === this.$parent.processStatus) {
- step = this.currentStatus !== 'error' ? 0 : 0;
- } else if (status === 'wait') {
- step = 0;
- style.transitionDelay = (-150 * this.index) + 'ms';
- }
- style.borderWidth = step && !this.isSimple ? '1px' : 0;
- this.$parent.direction === 'vertical'
- ? style.height = step + '%'
- : style.width = step + '%';
- this.lineStyle = style;
- }
- },
- mounted() {
- const unwatch = this.$watch('index', val => {
- this.$watch('$parent.active', this.updateStatus, { immediate: true });
- this.$watch('$parent.processStatus', () => {
- const activeIndex = this.$parent.active;
- this.updateStatus(activeIndex);
- }, { immediate: true });
- unwatch();
- });
- }
- };
- </script>
|