mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-03-01 13:36:55 +08:00
feature: the most basic of tab
This commit is contained in:
parent
c5c5c0b551
commit
aee78fab7a
111
demo/components/tabDemo.vue
Normal file
111
demo/components/tabDemo.vue
Normal 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>
|
@ -134,6 +134,10 @@ export default {
|
||||
{
|
||||
name: 'Form',
|
||||
path: '/n-form'
|
||||
},
|
||||
{
|
||||
name: 'Tab',
|
||||
path: '/n-tab'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -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 }
|
||||
]
|
||||
|
2
index.js
2
index.js
@ -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)
|
||||
}
|
||||
|
||||
|
9
packages/common/Tab/index.js
Normal file
9
packages/common/Tab/index.js
Normal 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
|
50
packages/common/Tab/src/TabPanel.vue
Normal file
50
packages/common/Tab/src/TabPanel.vue
Normal 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>
|
89
packages/common/Tab/src/main.vue
Normal file
89
packages/common/Tab/src/main.vue
Normal 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
22
styles/Tab.scss
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@
|
||||
@import './Radio.scss';
|
||||
@import './Form.scss';
|
||||
@import './TimePicker.scss';
|
||||
@import './Tab.scss';
|
||||
|
||||
@import "./NimbusServiceLayout.scss";
|
||||
@import "./Popover.scss";
|
||||
|
Loading…
Reference in New Issue
Block a user