104 lines
2.8 KiB
Vue
104 lines
2.8 KiB
Vue
<template>
|
|
<section class="navTabs flex pad-h8 pad-v8">
|
|
<div class="fill flex">
|
|
<div class="item pad-h8" v-text="`首页`" :class="{current:$route.name=='工作台'}" @click="$router.push({name:'工作台'})"/>
|
|
<div class="item pad-h8 flex center" v-for="item in tabs" :key="item.id"
|
|
:class="{current:item.name==$route.name}" @click="handleJump(item)">
|
|
<div class="mar-r8" v-text="item.label"/>
|
|
<el-icon @click.stop="handleClosePage(item.id)">
|
|
<Close/>
|
|
</el-icon>
|
|
</div>
|
|
</div>
|
|
<el-dropdown class="mar-l8" @command="handleOpt">
|
|
<el-button>更多</el-button>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item command="clearAllPages">关闭全部</el-dropdown-item>
|
|
<el-dropdown-item command="clearOtherPages">关闭其他</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</section>
|
|
</template>
|
|
|
|
<script>
|
|
import {mapActions, mapState} from "pinia/dist/pinia";
|
|
import {mainStore} from "../utils/store";
|
|
import {Close} from "@element-plus/icons-vue";
|
|
|
|
export default {
|
|
name: "navTabs",
|
|
components: {Close},
|
|
computed: {
|
|
...mapState(mainStore, ['pages']),
|
|
tabs: v => v.pages
|
|
},
|
|
methods: {
|
|
...mapActions(mainStore, ['deletePage', 'clearOtherPages']),
|
|
handleClosePage(id) {
|
|
const {pages} = this
|
|
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.handleJump({name: next.id})
|
|
}
|
|
this.deletePage(id)
|
|
},
|
|
handleJump(page) {
|
|
const {name} = page
|
|
name != this.$route.fullPath && this.$router.push(name)
|
|
},
|
|
handleOpt(v) {
|
|
const opts = {
|
|
clearAllPages: () => {
|
|
mainStore().clearAllPages()
|
|
this.handleJump({name: "/"})
|
|
},
|
|
clearOtherPages: this.clearOtherPages
|
|
}
|
|
opts[v]();
|
|
}
|
|
},
|
|
watch: {
|
|
$route: {
|
|
immediate: true,
|
|
handler(v) {
|
|
const currentPage = this.pages.find(e => e.name == v.name);
|
|
currentPage && this.addPage(currentPage)
|
|
}
|
|
}
|
|
},
|
|
created() {
|
|
const currentPage = JSON.parse(localStorage.getItem("apps") || null)?.find(e => e.name == this.$route.name);
|
|
currentPage && mainStore().addPage(currentPage)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.navTabs {
|
|
.item {
|
|
border-radius: 4px;
|
|
border: 1px solid #ccc;
|
|
line-height: 30px;
|
|
font-size: 14px;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
color: #999;
|
|
justify-self: flex-start;
|
|
flex-shrink: 0;
|
|
|
|
&.current {
|
|
color: #fff;
|
|
background: var(--el-color-primary);
|
|
border-color: transparent;
|
|
}
|
|
|
|
& + .item {
|
|
margin-left: 8px;
|
|
}
|
|
}
|
|
}
|
|
</style>
|