feature: the most basic of tab

This commit is contained in:
mangogan 2019-07-29 16:40:11 +08:00
parent c5c5c0b551
commit aee78fab7a
9 changed files with 290 additions and 0 deletions

111
demo/components/tabDemo.vue Normal file
View File

@ -0,0 +1,111 @@
<template>
<div
ref="doc"
class="n-doc"
>
<div class="n-doc-header">
<n-gradient-text :font-size="20">
Tab / hahah
</n-gradient-text>
</div>
<div class="n-doc-body">
<div class="n-doc-section">
<div class="n-doc-section__header">
Basic Usage
</div>
<div class="n-doc-section__view">
<n-tab>
<n-tab-panel label="form">
<n-form
inline
:label-width="80"
>
<n-form-item label="name">
<n-input placeholder="Input your name" />
</n-form-item>
<n-form-item label="age">
<n-input placeholder="Input your age" />
</n-form-item>
<n-form-item label="phone">
<n-input placeholder="Input your phone number" />
</n-form-item>
</n-form>
</n-tab-panel>
<n-tab-panel label="lal">
<n-advance-table
:columns="columns0"
:data="data"
>
<template #table-operation>
<n-button>custom operation by v-slot:table-operation</n-button>
</template>
</n-advance-table>
</n-tab-panel>
</n-tab>
</div>
<div class="n-doc-section__source" />
</div>
</div>
</div>
</template>
<script>
import docCodeEditorMixin from './docCodeEditorMixin'
export default {
mixins: [docCodeEditorMixin],
data () {
let d = new Array(20).fill(0)
d = d.map((item, idx) => {
return {
name: 'xiaobai' + idx,
age: Math.ceil((Math.random() * 20))
}
})
return {
data: d,
columns0: [
{
title: 'Name',
key: 'name',
width: 300
},
{
title: '#',
render: (h, params) => {
return (
<n-button
style="margin:0;"
size="small"
onClick={() => this.handleClick(params)}
>
delete
</n-button>
)
}
},
{
title: 'Age',
key: 'age',
render: (h, params) => {
return <b>{params.row.age}</b>
}
},
{
title: '#',
render: (h, params) => {
return (
<n-button
style="margin:0;"
size="small"
onClick={() => this.handleClick(params)}
>
delete
</n-button>
)
}
}]
}
}
}
</script>

View File

@ -134,6 +134,10 @@ export default {
{
name: 'Form',
path: '/n-form'
},
{
name: 'Tab',
path: '/n-tab'
}
]
},

View File

@ -27,6 +27,7 @@ import inputNumberDemo from './components/inputNumberDemo'
import nimbusIconDemo from './components/nimbusIconDemo'
import radioDemo from './components/radioDemo'
import formDemo from './components/formDemo'
import tabDemo from './components/tabDemo'
import timePickerDemo from './components/timePickerDemo'
import notificationDemo from './components/notificationDemo'
@ -82,6 +83,7 @@ const routes = [
{ path: '/n-nimbus-icon', component: nimbusIconDemo },
{ path: '/n-radio', component: radioDemo },
{ path: '/n-form', component: formDemo },
{ path: '/n-tab', component: tabDemo },
{ path: '/n-time-picker', component: timePickerDemo },
{ path: '/n-router-debug', component: routerDebug }
]

View File

@ -24,6 +24,7 @@ import DatePicker from './packages/common/DatePicker'
import InputNumber from './packages/common/InputNumber'
import Radio from './packages/common/Radio'
import Form from './packages/common/Form'
import Tab from './packages/common/Tab'
import TimePicker from './packages/common/TimePicker'
import ServiceCard from './packages/nimbus/ServiceCard'
import HomeLayout from './packages/nimbus/HomeLayout'
@ -67,6 +68,7 @@ function install (Vue) {
NimbusIcon.install(Vue)
Radio.install(Vue)
Form.install(Vue)
Tab.install(Vue)
TimePicker.install(Vue)
}

View File

@ -0,0 +1,9 @@
import Tab from './src/main.vue'
import NTabPanel from './src/TabPanel.vue'
Tab.install = function (Vue) {
Vue.component(Tab.name, Tab)
Vue.component(NTabPanel.name, NTabPanel)
}
export default Tab

View File

@ -0,0 +1,50 @@
<template>
<div class="NTabPanel">
<div v-show="isShow">
<slot />
</div>
</div>
</template>
<script>
export default {
name: 'NTabPanel',
inject: [ 'NTab' ],
props: {
label: {
type: String,
default: undefined
},
name: {
type: String || Number,
default: undefined
},
active: {
type: Boolean,
default: false
}
},
data () {
return {
isShow: false
}
},
computed: {
},
created () {
this.NTab.updateLabels()
this.initActive()
},
methods: {
updateIsShow (flag) {
this.isShow = flag
// ()
},
initActive () {
if ((this.active || this.NTab.name === this.name) && this.NTab.active === null) {
this.updateIsShow(true)
this.NTab.initActive()
}
}
}
}
</script>

View File

@ -0,0 +1,89 @@
<template>
<div
class="n-tab"
>
<div
class="n-tab--label"
>
<div
v-for="(label, i) in labels"
:key="i"
class="n-tab--label-item"
@click="updateActive($event, i)"
>
{{ label }}
</div>
</div>
<slot />
</div>
</template>
<script>
export default {
name: 'NTab',
provide () {
return {
NTab: this
}
},
props: {
name: {
type: String || Number,
default: undefined
}
},
data () {
return {
labels: [],
active: null // number
}
},
created () {
// this.updateOrder()
// this.initActive()
},
beforeMount () {
console.log('slot', this.$slots)
},
mounted () {
if (this.active === null) {
this.active = 0
let panel = this.$children.find(i => { return i.$options.name === 'NTabPanel' })
panel.updateIsShow(true)
}
},
methods: {
updateLabels () {
let labels = []
this.$children.forEach((i, order) => {
if (i.$options.name === 'NTabPanel') {
labels.push(i.label || '')
i._NaiveTabOrder = order
}
})
this.$set(this, 'labels', labels)
},
initActive () {
// let res = this.$children.findIndex(i => { return i.$options.name === 'NTabPanel' && i.active })
// let order = res > -1 ? res : 0
// this.$children[order].updateIsShow(true)
// this.active = order
this.active = this.labels.length - 1
},
updateActive (e, i) {
if (e.target.className === 'n-tab--label-item' && i !== this.active) {
this.$children[this.active].updateIsShow(false)
this.active = i
this.$children[i].updateIsShow(true)
}
},
updateOrder () {
// method duplicate with updateLabels
this.$children.forEach((i, order) => {
if (i.$options.name === 'NTabPanel') {
i._NaiveTabOrder = order
}
})
}
}
}
</script>

22
styles/Tab.scss Normal file
View File

@ -0,0 +1,22 @@
@import './mixins/mixins.scss';
@import './theme/default.scss';
@include b(tab) {
display: block;
width: 100%;
height: 100%;
.n-tab--label {
display: flex;
align-items: center;
justify-items: flex-start;
background-color: bisque;
padding-bottom: 10px;
.n-tab--label-item {
padding: 2px 5px;
border-right: 1px solid #cccccc;
}
.n-tab--label-item_active {
color: aquamarine;
}
}
}

View File

@ -23,6 +23,7 @@
@import './Radio.scss';
@import './Form.scss';
@import './TimePicker.scss';
@import './Tab.scss';
@import "./NimbusServiceLayout.scss";
@import "./Popover.scss";