JSFiddle - React, Tailwind, and code Playground
by ozzon91
HTML
<div id="app">
<wizard>
<wz-step :disable="d">
<h1>Step one</h1>
</wz-step>
<wz-step :disable="d2">
<h1>Step two</h1>
</wz-step>
<wz-step>
<h1>Step three</h1>
</wz-step>
<wz-prev>Prev</wz-prev>
<wz-next>Next</wz-next>
</wizard>
<button @click="toggle">Step one disable:{{d}}</button>
<button @click="toggle2">Step two disable:{{d2}}</button>
</div>
<template id="t-wizard">
<div class="wizard">
<slot></slot>
<p style="text-align: center;">
<span v-for="(s,i) in steps" class="nav-item" :class="{'active': i === currentIndex}"></span>
</p>
</div>
</template>
<template id="t-wz-step">
<div class="wizard__step" :class="{'wizard__step--current': isCurrent}">
<slot></slot>
</div>
</template>
<template id="t-wz-prev">
<button @click="prev"><slot></slot></button>
</template>
<template id="t-wz-next">
<button @click="next"><slot></slot></button>
</template>
SCSS
.wizard {
.nav-item {
background: green;
border-radius: 50%;
display: inline-block;
margin-right: 3px;
right: 3px;
width: 15px;
height: 15px;
&.active {
background: red;
}
}
&__step {
display: none;
&--current {
display: block;
}
}
}
Babel + JSX
Vue.component('wizard', {
name: 'wizard',
template: '#t-wizard',
mounted: function() {
this.refreshSteps();
if(this.steps.length) {
if(!this.currentStep) {
this.steps[0].isCurrent = true;
}
}
},
methods: {
refreshSteps() {
let hasDisabledCurrentStep = -1;
this.stepsAll = this.$children.filter(el => el.$options.name === 'wz-step');
this.steps = this.$children.filter(el => el.$options.name === 'wz-step' && !el.disable);
this.stepsAll.forEach((el, i) => {
if(el.$options.name === 'wz-step' && el.isCurrent && el.disable) {
hasDisabledCurrentStep = i;
}
});
console.log('hasDisabledCurrentStep', hasDisabledCurrentStep)
if(hasDisabledCurrentStep != -1) {
for(let i = hasDisabledCurrentStep; i < this.stepsAll.length; ++i) {
if(!this.stepsAll[i].disable) {
this.currentStep = this.stepsAll[i];
break;
}
}
if(hasDisabledCurrentStep > 0 && !this.currentStep) {
for(let i = hasDisabledCurrentStep; i > 0; --i) {
if(!this.stepsAll[i].disable) {
this.currentStep = this.stepsAll[i];
break;
}
}
}
if(this.currentStep) {
this.stepsAll[hasDisabledCurrentStep].isCurrent = false;
let index = this.steps.findIndex(el => this.currentStep.$el === el.$el);
this.currentIndex = index;
this.steps[this.currentIndex].isCurrent = true;
}
} else {
let index = this.steps.findIndex(el => el.isCurrent);
if(index != -1) this.currentIndex = index;
this.currentStep = null;
}
},
next() {
let index = this.steps.findIndex(el => el.isCurrent);
if((index != -1) && index < this.steps.length-1) {
this.currentIndex = index+1;
...