feature: most funciton

This commit is contained in:
mangogan 2019-08-01 17:15:29 +08:00
parent b7ecdc2b80
commit 485be90f10
7 changed files with 246 additions and 35 deletions

View File

@ -299,6 +299,17 @@
:items="items"
/>
</n-form-item>
<n-form-item
prop="mutiSelect.0"
label="multi-select"
>
<n-select
v-model="validateForm.mutiSelect[0]"
multiple
placeholder="Please Select Type"
:items="items"
/>
</n-form-item>
<n-form-item
label="Switch"
prop="switch"
@ -701,6 +712,10 @@ export default {
callback()
}
}
let arrayValidate = (rule, value, callback) => {
console.log('arrya validate value', value)
debugger
}
return {
form: {
name: '',
@ -738,6 +753,9 @@ export default {
select: 'Public'
}
},
mutiSelect: [
[]
],
datepicker: 0,
switch: false,
radio: ''
@ -746,6 +764,9 @@ export default {
input: [
{ required: true, message: 'input cannot be empty', trigger: 'blur' }
],
'mutiSelect.0': [{
validator: arrayValidate, trigger: 'change'
}],
'muti.deep.select': [
{
required: true,
@ -890,7 +911,6 @@ export default {
console.log('unpass', e)
})
},
formReset (ref) {
this.$refs[ref].resetForm()
},

View File

@ -14,7 +14,12 @@
Basic Usage
</div>
<div class="n-doc-section__view">
<n-tab>
<n-tab
type="card"
closable
addable
:add-panel="addPanel"
>
<n-tab-panel label="form">
<n-form
inline
@ -44,9 +49,25 @@
</template>
</n-advance-table>
</n-tab-panel>
<n-tab-panel label="input">
<n-tab-panel
disabled
label="input"
>
haha: <n-input />
</n-tab-panel>
<n-tab-panel label="icon">
lala: <n-icon />
</n-tab-panel>
<n-tab-panel label="button">
hehe: <n-button />
</n-tab-panel>
<n-tab-panel
v-for="(item, i) in panels"
:key="i"
:label="item.label"
>
{{ item.content }}
</n-tab-panel>
</n-tab>
</div>
<div class="n-doc-section__source" />
@ -68,6 +89,7 @@ export default {
}
})
return {
panels: [],
data: d,
columns0: [
{
@ -111,7 +133,14 @@ export default {
}
}]
}
},
methods: {
addPanel () {
this.panels.push({
label: this.panels.length,
content: 'i am number' + this.panels.length
})
}
}
}
</script>

View File

@ -10,7 +10,6 @@
</template>
<script>
import { deepClone, getObjValue } from '../../../utils/index'
import { debuglog } from 'util';
export default {
name: 'NForm',

View File

@ -1,5 +1,7 @@
<template>
<div
v-if="unDelete"
ref="tab-panel"
:class="cls"
:style="style"
>
@ -12,7 +14,7 @@ export default {
inject: [ 'NTab' ],
props: {
label: {
type: String,
type: [String, Number],
default: undefined
},
name: {
@ -22,10 +24,19 @@ export default {
active: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
closable: {
type: Boolean,
default: false
}
},
data () {
return {
unDelete: true,
isShow: false,
style: {}
}
@ -42,7 +53,7 @@ export default {
offset: {
handler (n) {
this.setTransfer(n)
console.log('zhixing', n)
this.$forceUpdate()
},
immediate: true
}
@ -52,16 +63,28 @@ export default {
if (this._NaiveTabOrder === this.NTab.active) {
this.updateIsShow(true)
}
this.$on('display-none', this.setDisplayNone)
},
beforeDestroy () {
console.log('before destory call')
this.$off('display-none', this.setDisplayNone)
},
methods: {
updateIsShow (flag) {
this.isShow = flag
this.$forceUpdate()
// window.getComputedStyle(this.NTab.refs['slot'], null).getPropertyValue('width')
// this.$refs['panel'].classList.toggle('n-tab-panel_active')
// ()
},
setTransfer (per) {
this.style.transform = 'translateX(' + per + ')'
},
setDisplayNone (i) {
if (i === this._NaiveTabOrder) {
// this.$set(this.style, 'display', 'none')
this.unDelete = false
}
}
}
}

View File

@ -3,16 +3,25 @@
class="n-tab"
>
<div
class="n-tab--label"
:class="addable ? 'n-tab--label_addable n-tab--label' : 'n-tab--label'"
>
<div
v-for="(label, i) in labels"
:key="i"
class="n-tab--label-item"
:class="getClass(i)"
@click="updateActive($event, i)"
>
{{ label }}
<span class="n-tab--label-content">{{ label }}
<span class="n-tab--label-delete"> + </span>
</span>
</div>
<n-button
size="small"
class="n-tab--label-add"
@click="addPanelItem"
>
+
</n-button>
</div>
<div
ref="slot"
@ -23,6 +32,8 @@
</div>
</template>
<script>
import Emitter from '../../../mixins/emitter'
export default {
name: 'NTab',
provide () {
@ -30,26 +41,42 @@ export default {
NTab: this
}
},
mixins: [ Emitter ],
props: {
name: {
type: String || Number,
default: undefined
},
closable: {
type: Boolean,
default: undefined
},
type: {
type: String,
default: 'normal' // card board?
},
addable: {
type: Boolean,
default: false
},
addPanel: {
type: Function,
default: () => {}
}
},
data () {
return {
labels: [],
active: null, // number
offset: null
offset: null,
prefix: 'n-tab--label'
}
},
computed: {
},
created () {
this.updateOrder()
this.initOffset()
// this.initActive()
},
beforeMount () {
console.log('slot', this.$slots)
},
mounted () {
if (this.active === null) {
@ -59,35 +86,66 @@ export default {
}
},
methods: {
getClass (i) {
let panel = this.getTabPanel(i) || {}
let cName = this.prefix + '-item '
cName += (panel.disabled ? this.prefix + '-item_disabled ' : '')
cName += (this.active === i ? this.prefix + '-item_active ' : '')
cName += this.type === 'card' ? this.prefix + '-item_card ' : ''
cName += this.type === 'card' && (this.closable || panel.closable) ? this.prefix + '-item_close ' : ''
// cName += this.addable ? this.prefix + '-item_addable ' : ''
return cName
},
updateLabels () {
let labels = []
this.$children.forEach((i, order) => {
let j = 0
this.$children.forEach((i) => {
if (i.$options.name === 'NTabPanel') {
labels.push(i.label || '')
i._NaiveTabOrder = order
i._NaiveTabOrder = j++
}
})
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)
let eName = e.target.className
let eParentName = e.target.parentElement.className
let isLabel = eName.indexOf('n-tab--label-item') > -1 || eParentName.indexOf('n-tab--label-item') > -1
if (eName === 'n-tab--label-delete') {
// steps while deleting, need to set display none to label and the tab panel and then init the display
this.labels.splice(i, 1)
this.broadcast('NTabPanel', 'display-none', i)
this.updateOrder(false)
if (this.active === i) {
this.active = 0
this.getTabPanel(this.active).updateIsShow(true)
} else {
this.active = i > this.active ? this.active : this.active - 1
}
this.offset = '-' + this.active * 100 + '%'
} else if (isLabel && i !== this.active) {
this.getTabPanel(this.active).updateIsShow(false)
this.active = i
this.$children[i].updateIsShow(true)
let temp = this.getTabPanel(i)
console.log(temp, this.$children, i)
temp.updateIsShow(true)
this.offset = '-' + this.active * 100 + '%'
}
},
updateOrder () {
updateOrder (init = true) {
// method duplicate with updateLabels
this.$slots.default.forEach((i, order) => {
i._NaiveTabOrder = order
let j = 0
let arr = init ? this.$slots.default : this.$children
arr.forEach((i) => {
if (init || i.unDelete) {
i._NaiveTabOrder = j++
} else {
delete i._NaiveTabOrder
}
})
},
initOffset () {
@ -103,6 +161,17 @@ export default {
})
this.active = order > -1 ? order : 0
this.offset = '-' + this.active * 100 + '%'
console.log('active', this.active)
},
getTabPanel (i) {
if (i === undefined) return
return this.$children.find(c => {
return c._NaiveTabOrder === i
})
},
addPanelItem () {
this.addPanel()
this.updateOrder(false)
}
}
}

View File

@ -1,6 +1,6 @@
function broadcast (componentName, eventName, params) {
this.$children.forEach(child => {
let name = child.$options.componentName
let name = child.$options.name
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params))
} else {

View File

@ -4,18 +4,88 @@
@include b(tab) {
width: 100%;
height: 100%;
background-color: #171D33;
.n-tab--label {
display: flex;
align-items: center;
justify-items: flex-start;
background-color: bisque;
padding-bottom: 10px;
font-weight: bold;
font-size: 15px;
margin-top: 8px;
margin-bottom: 8px;
color: #ffffff;
// .n-tab--label-item:not(:last-child) {
// margin-right: 25px;
// }
.n-tab--label-item {
padding: 2px 5px;
border-right: 1px solid #cccccc;
margin-left: 25px;
padding-bottom: 8px;
// .n-tab--label-content {
// padding-bottom: 8px;
// border-bottom: 0px solid rgba(99, 226, 183, 1);
// }
.n-tab--label-delete {
display: none;
margin-left: 9px;
}
&:hover {
color: #55E8C7;
// border-bottom: 2px;
// border-bottom: 2px solid rgba(99, 226, 183, 1);
}
}
.n-tab--label-item_active {
color: aquamarine;
color: #63E2B7;
// border-bottom: 2px;
border-bottom: 2px solid rgba(99, 226, 183, 1);
}
.n-tab--label-item_delete {
.n-tab--label-delete {
display: inline-block;
}
}
.n-tab--label-item_disabled {
color: #FFFFFF;
opacity: 0.3;
pointer-events: none;
}
.n-tab--label-item_card {
margin-left: 0;
margin-right: 6px;
padding: 8px 16px;
border-radius: 6px 6px 0 0;
background-color: rgba(255, 255, 255, 0.3);
.n-tab--label-content {
border: none;
color: #50E3C2
}
&.n-tab--label-item_active {
border: none;
}
&:hover {
color: #55E8C7;
border: none;
}
&.n-tab--label-item_close {
.n-tab--label-delete {
display: inline-block;
margin-left: 9px;
}
}
}
// .n-tab--label-item_active {
// color: #63E2B7;
// // border-bottom: 2px;
// border-bottom: 2px solid rgba(99, 226, 183, 1);
// }
.n-tab--label-add {
display: none;
}
&.n-tab--label_addable {
.n-tab--label-add {
display: inline-block;
}
}
}
.n-tab--slot {
@ -29,10 +99,11 @@
@include b(tab-panel) {
flex-shrink: 0;
width: 100%;
height: 100%;
visibility: hidden;
transition: transform 0.3s;
transition: transform 0.2s;
height: 0;
&.n-tab-panel_active {
visibility: visible;
height: 100%;
}
}