init
This commit is contained in:
66
admin/src/components/CustomTabPane.vue
Normal file
66
admin/src/components/CustomTabPane.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<div v-show="isActive" class="tab-pane">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CustomTabPane',
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isActive: false,
|
||||
parentTabs: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.findParentTabs()
|
||||
if (this.parentTabs) {
|
||||
this.parentTabs.registerTab({
|
||||
label: this.label,
|
||||
name: this.name
|
||||
})
|
||||
this.updateActiveState(this.parentTabs.activeTab)
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.parentTabs) {
|
||||
this.parentTabs.unregisterTab(this.name)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
findParentTabs() {
|
||||
let parent = this.$parent
|
||||
while (parent) {
|
||||
if (parent.$options.name === 'CustomTabs') {
|
||||
this.parentTabs = parent
|
||||
break
|
||||
}
|
||||
parent = parent.$parent
|
||||
}
|
||||
},
|
||||
updateActiveState(activeTab) {
|
||||
this.isActive = activeTab === this.name
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tab-pane {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
overflow-y: visible;
|
||||
}
|
||||
</style>
|
||||
|
||||
118
admin/src/components/CustomTabs.vue
Normal file
118
admin/src/components/CustomTabs.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="custom-tabs">
|
||||
<div class="tabs-header">
|
||||
<div
|
||||
v-for="tab in tabs"
|
||||
:key="tab.name"
|
||||
:class="['tab-item', { active: activeTab === tab.name }]"
|
||||
@click="handleTabClick(tab.name)">
|
||||
{{ tab.label }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabs-content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CustomTabs',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: this.value || '',
|
||||
tabs: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(newVal) {
|
||||
this.activeTab = newVal
|
||||
this.updateChildren()
|
||||
},
|
||||
activeTab(newVal) {
|
||||
this.updateChildren()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.updateChildren()
|
||||
},
|
||||
methods: {
|
||||
handleTabClick(name) {
|
||||
this.activeTab = name
|
||||
this.$emit('input', name)
|
||||
this.$emit('change', name)
|
||||
this.updateChildren()
|
||||
},
|
||||
registerTab(tab) {
|
||||
if (!this.tabs.find(t => t.name === tab.name)) {
|
||||
this.tabs.push(tab)
|
||||
// 如果没有激活的tab,设置第一个为激活
|
||||
if (!this.activeTab && this.tabs.length > 0) {
|
||||
this.activeTab = this.tabs[0].name
|
||||
this.$emit('input', this.activeTab)
|
||||
}
|
||||
}
|
||||
},
|
||||
unregisterTab(tabName) {
|
||||
const index = this.tabs.findIndex(t => t.name === tabName)
|
||||
if (index > -1) {
|
||||
this.tabs.splice(index, 1)
|
||||
}
|
||||
},
|
||||
updateChildren() {
|
||||
this.$children.forEach(child => {
|
||||
if (child.$options.name === 'CustomTabPane') {
|
||||
child.updateActiveState(this.activeTab)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.custom-tabs {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tabs-header {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #e8eaec;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
padding: 12px 24px;
|
||||
cursor: pointer;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: all 0.3s;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tab-item:hover {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
color: #333;
|
||||
border-bottom-color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tabs-content {
|
||||
padding: 20px 0;
|
||||
min-height: 400px;
|
||||
overflow-x: auto;
|
||||
overflow-y: visible;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user