效果:

vue2:
创建layout/index.vue
<template>
<el-container>
<el-container>
<el-aside :width="isCollapse ? '65px' : '200px'">
<Menu :isCollapse.sync="isCollapse"></Menu>
</el-aside>
<el-main class="main">
<el-header>
<Header :isCollapse.sync="isCollapse"></Header>
</el-header>
<el-main class="minMain">
<el-tabs
v-model="tabsEditableTabsValue"
type="card"
@tab-remove="removeTab"
@tab-click="onTab"
>
<el-tab-pane
v-for="item in editableTabs"
:closable="item.closable"
:key="item.name"
:label="item.title"
:name="item.name"
>
</el-tab-pane>
</el-tabs>
<router-view class="routerView"></router-view
></el-main>
</el-main>
</el-container>
</el-container>
</template>
<script>
import Header from "./components/header.vue";
import Menu from "./components/menu.vue";
import { mapState } from "vuex";
export default {
components: { Header, Menu },
data() {
return {
isCollapse: false,
};
},
methods: {
removeTab(targetName) {
let tabs = this.editableTabs;
let activeName = this.tabsEditableTabsValue;
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
let nextTab = tabs[index + 1] || tabs[index - 1];
if (nextTab) {
activeName = nextTab.name;
}
}
});
}
this.$store.commit("menuStore/setEditableTabsValue", activeName);
this.tabs = tabs.filter((tab) => tab.name !== targetName);
this.$store.commit("menuStore/setEditableTabs", this.tabs);
let dd = tabs.find((i) => i.name == activeName);
this.$store.commit("menuStore/setBreadcrumbe", {
path: dd.name,
title: dd.title,
});
this.$router.push(dd.name);
},
onTab(event) {
this.$router.push(event._props.name);
this.$store.commit("menuStore/setBreadcrumbe", {
path: event._props.name,
title: event._props.label,
});
},
},
computed: {
...mapState("menuStore", ["editableTabs", "editableTabsValue"]),
tabsEditableTabsValue: {
get() {
return this.editableTabsValue;
},
set(value) {
this.$store.commit("menuStore/setEditableTabsValue", value);
},
},
},
};
</script>
<style scoped lang="scss">
.el-container {
height: 100vh;
.el-aside {
color: #333;
background-color: #fcfcfd;
}
.main {
padding: 0;
background-color: #f5f5f5;
.el-header {
color: #333;
background-color: #fff;
}
.minMain {
background-color: #fff;
margin: 20px;
padding: 0;
height: calc(100% - 100px);
box-sizing: border-box;
.routerView {
padding: 0 10px;
box-sizing: border-box;
}
}
}
}
</style>
创建layout/components/header.vue
<template>
<div class="container dfcc">
<div class="left">
<i
:class="isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'"
class="icon"
@click="onIsCollapse"
></i>
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/schedule' }"
>schedule</el-breadcrumb-item
>
<el-breadcrumb-item>{
{
$store.state.menu.breadcrumb.title
}}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="right dfcc">
<el-dropdown>
<i class="el-icon-setting"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>查看</el-dropd