mirror of
https://github.com/tenrok/vue-form-wizard.git
synced 2026-06-13 09:12:25 +03:00
Add component files
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<tab-wizard>
|
||||
<tab-content title="Personal details">
|
||||
My first tab content
|
||||
</tab-content>
|
||||
<tab-content title="Additional Info">
|
||||
My second tab content
|
||||
</tab-content>
|
||||
<tab-content title="Last step">
|
||||
Yuhuuu! This seems pretty damn simple
|
||||
</tab-content>
|
||||
</tab-wizard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'app'
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div v-if="show">
|
||||
<slot>
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default{
|
||||
name: 'tab-content',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
beforeChange: {
|
||||
type: Function
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
show: false,
|
||||
active: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="header text-center">
|
||||
<h4 class="title">{{title}}</h4>
|
||||
<p class="category">{{subtitle}}</p>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div>
|
||||
<ul class="nav nav-pills">
|
||||
<li v-for="(tab, index) in tabs" :class="tab.active ? 'active' : ''">
|
||||
<a href="" @click.prevent="navigateToTab(index)">{{tab.title}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<slot>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button v-if="displayPrevButton" type="button" class="btn btn-default btn-fill btn-wd btn-back pull-left"
|
||||
@click="prevTab">
|
||||
{{backButtonText}}
|
||||
</button>
|
||||
<button v-if="isLastStep" type="button" class="btn btn-info btn-fill btn-wd btn-next pull-right" @click="nextTab">
|
||||
{{finishButtonText}}
|
||||
</button>
|
||||
<button v-else type="button" class="btn btn-info btn-fill btn-wd btn-next pull-right" @click="nextTab">
|
||||
{{nextButtonText}}
|
||||
</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default{
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: 'Awesome Wizard'
|
||||
},
|
||||
subtitle: {
|
||||
type: String,
|
||||
default: 'Split a complicated flow in multiple steps'
|
||||
},
|
||||
nextButtonText: {
|
||||
type: String,
|
||||
default: 'Next'
|
||||
},
|
||||
backButtonText: {
|
||||
type: String,
|
||||
default: 'Back'
|
||||
},
|
||||
finishButtonText: {
|
||||
type: String,
|
||||
default: 'Finish'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
activeTabIndex: 0,
|
||||
isLastStep: false,
|
||||
maxStep: 0,
|
||||
tabs: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tabCount () {
|
||||
return this.tabs.length
|
||||
},
|
||||
displayPrevButton () {
|
||||
return this.activeTabIndex !== 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
navigateToTab (index) {
|
||||
if (index <= this.maxStep && this.beforeTabChange(this.activeTabIndex)) {
|
||||
this.changeTab(this.activeTabIndex, index)
|
||||
}
|
||||
},
|
||||
beforeTabChange (index) {
|
||||
let oldTab = this.tabs[index]
|
||||
if (oldTab && oldTab.beforeChange !== undefined) {
|
||||
return oldTab.beforeChange()
|
||||
}
|
||||
return true
|
||||
},
|
||||
changeTab (oldIndex, newIndex) {
|
||||
let oldTab = this.tabs[oldIndex]
|
||||
let newTab = this.tabs[newIndex]
|
||||
if (oldTab) {
|
||||
oldTab.show = false
|
||||
oldTab.active = false
|
||||
}
|
||||
if (newTab) {
|
||||
newTab.show = true
|
||||
newTab.active = true
|
||||
}
|
||||
this.activeTabIndex = newIndex
|
||||
this.checkStep()
|
||||
return true
|
||||
},
|
||||
checkStep () {
|
||||
if (this.activeTabIndex === this.tabCount - 1) {
|
||||
this.isLastStep = true
|
||||
} else {
|
||||
this.isLastStep = false
|
||||
}
|
||||
},
|
||||
increaseMaxStep () {
|
||||
if (this.activeTabIndex > this.maxStep) {
|
||||
this.maxStep = this.activeTabIndex
|
||||
}
|
||||
},
|
||||
|
||||
nextTab () {
|
||||
if (!this.beforeTabChange(this.activeTabIndex)) return
|
||||
|
||||
if (this.activeTabIndex < this.tabCount - 1) {
|
||||
this.activeTabIndex++
|
||||
this.increaseMaxStep()
|
||||
this.checkStep()
|
||||
} else {
|
||||
this.isLastStep = true
|
||||
this.$emit('finished')
|
||||
}
|
||||
},
|
||||
prevTab () {
|
||||
if (!this.beforeTabChange(this.activeTabIndex)) return
|
||||
|
||||
if (this.activeTabIndex > 0) {
|
||||
this.activeTabIndex--
|
||||
this.isLastStep = false
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.tabs = this.$children.filter((comp) => comp.$options.name === 'tab-content')
|
||||
if (this.tabs.length > 0) {
|
||||
let firstTab = this.tabs[this.activeTabIndex]
|
||||
firstTab.show = true
|
||||
firstTab.active = true
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeTabIndex: function (newVal, oldVal) {
|
||||
if (this.beforeTabChange(oldVal)) {
|
||||
this.changeTab(oldVal, newVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.card-wizard .nav-pills {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.card-wizard .nav-pills li,
|
||||
.card-wizard .nav-pills a {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
|
||||
TabWizard: require('./components/TabWizard.vue'),
|
||||
TabContent: require('./components/TabContent.vue'),
|
||||
|
||||
install (Vue) {
|
||||
Vue.component('tab-wizard', module.exports.TabWizard)
|
||||
Vue.component('tab-content', module.exports.TabContent)
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// The Vue build version to load with the `import` command
|
||||
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import TabWizard from './index'
|
||||
Vue.use(TabWizard)
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
/* eslint-disable no-new */
|
||||
new Vue({
|
||||
el: '#app',
|
||||
template: '<App/>',
|
||||
components: {App}
|
||||
})
|
||||
Reference in New Issue
Block a user