diff --git a/README.md b/README.md
index 6416d38..d1890a0 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,7 @@ export default {
| tabs | tabs configuration. Details are mentioned below. | Array | [] |
| value / v-model | binding value | String | - |
| props | configuration options, Details are mentioned below. |
+| insert-to-after | Insert to tag's after | Boolean | false |
## Tabs Attributes
| Attributes | Description | Type | Default |
@@ -66,5 +67,19 @@ export default {
| label | specify which key of tab object is used as the tab's label | String | 'label' |
| key | specify which key of tab object is used as the tab's key | String | 'key' |
+## Methods
+| Method | Description | Parameters |
+| - | - | - |
+| addTab | add tab | (tab1, [, ...tab, ...tabN]) |
+| removeTab | remove tab | (tabKey | index) |
+| getTabs | get tabs | - |
+
+## Events
+| Event Name | Description | Parameters |
+| - | - | - |
+| swap | swap tab | (tab, targetTab) |
+| remove | remove tab | (tab, index) |
+| contextmenu | contextmenu event | (event, tab, index) |
+
## License
MIT
diff --git a/examples/App.vue b/examples/App.vue
index 0e49e44..fcc0ab7 100644
--- a/examples/App.vue
+++ b/examples/App.vue
@@ -3,11 +3,24 @@
vue-tabs-chrome
A Vue component for Chrome-like tabs.
Default
+
+ code
+
Theme Dark
+
+ code
+
Theme Custom
+
+ code
+
+ Insert to tag's after
+
+ Save to Localstorage
+
@@ -15,10 +28,12 @@
import Example from './example/example'
import ExampleDark from './example/example-dark'
import ExampleCustom from './example/example-custom'
+import ExampleInsert from './example/example-insert'
+import ExampleSave from './example/example-save'
export default {
name: 'app',
- components: { Example, ExampleDark, ExampleCustom }
+ components: { Example, ExampleDark, ExampleCustom, ExampleInsert, ExampleSave }
}
diff --git a/examples/example/example-insert.vue b/examples/example/example-insert.vue
new file mode 100644
index 0000000..4ecc9e0
--- /dev/null
+++ b/examples/example/example-insert.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
diff --git a/examples/example/example-save.vue b/examples/example/example-save.vue
new file mode 100644
index 0000000..6e7e867
--- /dev/null
+++ b/examples/example/example-save.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
diff --git a/examples/example/example.vue b/examples/example/example.vue
index 38fe3b2..422daa2 100644
--- a/examples/example/example.vue
+++ b/examples/example/example.vue
@@ -3,6 +3,7 @@
+
@@ -37,6 +38,9 @@ export default {
]
this.$refs.tab.addTab(...newTabs)
this.tab = item
+ },
+ removeTab () {
+ this.$refs.tab.removeTab(this.tab)
}
}
}
diff --git a/packages/vue-tabs-chrome.vue b/packages/vue-tabs-chrome.vue
index 2bafba5..4f58b43 100644
--- a/packages/vue-tabs-chrome.vue
+++ b/packages/vue-tabs-chrome.vue
@@ -11,6 +11,7 @@
:class="[{ active: tab[tabKey] === value }, `tab-${tab[tabKey]}`]"
:key="tab[tabKey]"
:style="{ width: tabWidth + 'px' }"
+ @contextmenu="e => handleMenu(e, tab, i)"
)
.tabs-background
.tabs-background-content
@@ -113,6 +114,10 @@ export default {
type: Number,
default: 7
},
+ insertToAfter: {
+ type: Boolean,
+ default: false
+ },
theme: {
type: String,
default: ''
@@ -174,12 +179,37 @@ export default {
tab._instance.on('dragEnd', (e, pointer) => this.handleDraEnd(e, tab, i))
},
addTab (...tabs) {
- this.tabs.push(...tabs)
+ let { insertToAfter, value, tabKey } = this
+ if (insertToAfter) {
+ let i = this.tabs.findIndex(tab => tab[tabKey] === value)
+ this.tabs.splice(i + 1, 0, ...tabs)
+ } else {
+ this.tabs.push(...tabs)
+ }
this.$nextTick(() => {
this.setup()
this.doLayout()
})
},
+ removeTab (key) {
+ let { tabKey, tabs } = this
+ let index = -1
+ let targetTab = null
+ if (typeof tab === 'number') {
+ index = key
+ targetTab = this.tabs[index]
+ } else {
+ tabs.forEach((tab, i) => {
+ if (tab[tabKey] === key) {
+ index = i
+ targetTab = tab
+ }
+ })
+ }
+ if (index >= 0 && targetTab) {
+ this.handleDelete(targetTab, index)
+ }
+ },
doLayout () {
this.calcTabWidth()
let { tabWidth, tabs, gap } = this
@@ -193,11 +223,20 @@ export default {
handleDelete (tab, i) {
let { tabKey, tabs, value } = this
let index = tabs.findIndex(item => item[tabKey] === value)
+ let after, before
if (i === index) {
- let before = tabs[i - 1]
- this.$emit('input', before ? before[tabKey] : null)
+ after = tabs[i + 1]
+ before = tabs[i - 1]
+ }
+ if (after) {
+ this.$emit('input', after[tabKey])
+ } else if (before) {
+ this.$emit('input', before[tabKey])
+ } else if (tabs.length <= 1) {
+ this.$emit('input', null)
}
tabs.splice(i, 1)
+ this.$emit('remove', tab, i)
this.$nextTick(() => {
this.doLayout()
})
@@ -230,6 +269,9 @@ export default {
_instance.element.classList.remove('move')
}, 200)
},
+ handleMenu (e, tab, index) {
+ this.$emit('contextmenu', e, tab, index)
+ },
swapTab (tab, targetTab) {
let { tabKey, tabs } = this
let index, targetIndex
@@ -257,7 +299,18 @@ export default {
}, 50)
setTimeout(() => {
_instance.element.classList.remove('move')
+ this.$emit('swap', tab, targetTab)
}, 200)
+ },
+ getTabs () {
+ return this.tabs.map(tab => {
+ let item = {
+ ...tab
+ }
+ delete item._instance
+ delete item._x
+ return item
+ })
}
}
}
@@ -406,7 +459,7 @@ export default {
}
.tabs-background-before,
.tabs-background-after {
- bottom: 0;
+ bottom: -1px;
position: absolute;
fill: transparent;
transition: background @speed;