169 lines
3.9 KiB
Vue
169 lines
3.9 KiB
Vue
<template>
|
|
<section class="AiNavTab">
|
|
<el-tabs class="layout fill" type="card" :value="currentTab" @tab-click="handleTabClick" @tab-remove="handleTabRemove">
|
|
<el-tab-pane v-for="(op,i) in tabs" :key="i" :name="op.id" :label="op.label" lazy :closable="!op.fixed"/>
|
|
</el-tabs>
|
|
<el-dropdown flex class="more" @visible-change="handleIcon" trigger="click" @command="handleOpt">
|
|
<ai-icon :icon="dropdownIcon"/>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item command="clearAllPages">关闭所有</el-dropdown-item>
|
|
<el-dropdown-item command="clearOtherPages">只留当前页</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</el-dropdown>
|
|
</section>
|
|
</template>
|
|
|
|
<script>
|
|
import {mapMutations, mapState} from "vuex";
|
|
|
|
export default {
|
|
name: "AiNavTab",
|
|
props: {
|
|
routes: {default: () => []},
|
|
fixed: {default: () => ({label: "首页", id: "/"})}
|
|
},
|
|
computed: {
|
|
...mapState(['logs']),
|
|
currentTab: v => v.isHome ? v.fixed.id : v.$route.fullPath,
|
|
tabs: v => [{...v.fixed, fixed: 1}, v.logs.pages].flat(),
|
|
isHome: v => v.fixed.id == v.$route.fullPath
|
|
},
|
|
data() {
|
|
return {
|
|
dropdownIcon: "iconDouble_Down"
|
|
}
|
|
},
|
|
watch: {
|
|
$route: {
|
|
immediate: true,
|
|
handler(v) {
|
|
const currentPage = this.routes.find(e => e.name == v.name);
|
|
currentPage && this.addPage(currentPage)
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
...mapMutations(['addPage', 'deletePage']),
|
|
handleTabClick(pageTab) {
|
|
const {name} = pageTab
|
|
name != this.$route.fullPath && this.$router.push(name)
|
|
},
|
|
handleTabRemove(id) {
|
|
const {pages} = this.logs
|
|
if (id == this.currentTab) {
|
|
const index = pages.findIndex(e => e.id == id)
|
|
const next = pages?.[index + 1] || pages?.[index - 1] || {id: this.fixed.id || "/"}
|
|
this.handleTabClick({name: next.id})
|
|
}
|
|
this.deletePage(id)
|
|
},
|
|
handleIcon(v) {
|
|
this.dropdownIcon = v ? "iconDouble_Up" : "iconDouble_Down"
|
|
},
|
|
handleOpt(v) {
|
|
this.$store.commit(v)
|
|
v == "clearAllPages" && this.handleTabClick({name: this.fixed.id || "/"})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.AiNavTab {
|
|
display: flex;
|
|
background: linear-gradient(180deg, #FCFCFC 0%, #E0E2E4 100%);
|
|
|
|
:deep(.layout ) {
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
.el-tabs__nav-prev, .el-tabs__nav-next {
|
|
top: 50%;
|
|
line-height: normal;
|
|
transform: translateY(-50%);
|
|
|
|
& > i {
|
|
font-weight: bold !important;
|
|
}
|
|
|
|
}
|
|
|
|
& > .el-tabs__header {
|
|
margin-bottom: 0;
|
|
height: 40px;
|
|
display: flex;
|
|
align-items: flex-end;
|
|
border: none;
|
|
|
|
.el-tabs__nav {
|
|
border: none;
|
|
}
|
|
|
|
.el-tabs__item {
|
|
padding: 0 8px 0 12px !important;
|
|
text-align: left;
|
|
min-width: 130px;
|
|
height: 36px;
|
|
line-height: 36px;
|
|
border: none;
|
|
color: #555;
|
|
font-size: 12px;
|
|
|
|
& + .el-tabs__item {
|
|
margin-left: 2px;
|
|
}
|
|
|
|
.el-icon-close {
|
|
float: right;
|
|
width: auto;
|
|
height: 100%;
|
|
line-height: 36px;
|
|
background: transparent;
|
|
font-size: 16px;
|
|
color: #89b;
|
|
|
|
&:hover {
|
|
color: #000;
|
|
}
|
|
}
|
|
|
|
&.is-active {
|
|
border: 1px solid #D8DCE3;
|
|
border-bottom: none;
|
|
border-radius: 4px 4px 0 0;
|
|
background: #F5F6F9;
|
|
color: #222;
|
|
|
|
&:after {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
&:after {
|
|
position: absolute;
|
|
right: 0;
|
|
content: " ";
|
|
width: 1px;
|
|
background: #D8DCE3;
|
|
height: 24px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
:deep(.more) {
|
|
.AiIcon {
|
|
height: 100%;
|
|
|
|
.iconfont {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|