导图

效果图

相关代码
vuex的代码
01-getters.js
getToolData(state){
return state.toolBarData;
},
getCacheView(state){
return state.cacheView;
},
02-actions.js
export const actions = {
commitToolBar({commit},data) {
commit("setToolData",data);
commit("setCacheView",data);
},
clearToolBar({commit},data){
commit("clearToolItem",data.detail);
},
clearCache({commit},data){
commit("clearCacheView",data);
}
}
03-mutations.js
import router from './../router'
export const mutations = {
setToolData(state, data) { // 添加标签按钮,如果当前路由已经打开,则不再重复添加
const inToolbar = state.toolBarData.find(item => item.detail === data.detail)
!inToolbar && state.toolBarData.push({
...data
});
},
setCacheView(state,data){ // 与setToolData类似
if(state.cacheView.includes(data.componentName))
return;
state.cacheView.push(data.componentName);
},
clearToolItem(state,detail){
const index = state.toolBarData.findIndex(item => item.detail === detail);
const isActive = router.app.$route.path == state.toolBarData[index]["detail"];
const len = state.toolBarData.length - 1;
state.toolBarData.splice(index,1);
(index == len || isActive) && router.push({path:state.toolBarData[state.toolBarData.length - 1]["detail"]});
},
clearCacheView(state,viewName){
const index = state.cacheView.findIndex(item => item == viewName);
state.cacheView.splice(index,1);
},
}
CommonTools.vue
<template>
<div class="commonToolsWrap" v-if="getToolData&&getToolData.length">
<div class="commonTools">
<el-tag
class="tabToolItem"
type="info"
:disable-transitions="false"
:closable="item.id != 0"
effect="plain"
v-for="(item,index) in getToolData"
:key="index"
:class="{active:$route.path == item.detail}"
@click="redirect(item)"
@close="closeToolItem(item)"
>
<span class="dot" v-if="$route.path == item.detail"></span>
<span class="txt">{{item.name}}</span>
</el-tag>
</div>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
methods: {
closeToolItem(item, index) {
this.$store.dispatch("clearToolBar", item);
this.$store.dispatch("clearCache", item.componentName);
},
redirect(item) {
this.$router.push({ path: item.detail });
}
},
computed: {
...mapGetters(["getToolData", "getCacheView"])
},
watch: {
// 监听路由变化自动dispatch一个action
$route() {
console.log(this.$route)
// 路由组件名称(自定义) 过滤用 include
const componentName =this.$route.matched[0]["components"]["default"]["name"];
// 路由组件path
const detail = this.$route.path;
// 当前路由需要显示到tab标签上名字,如 '直接入库'
// const name = this.$route.meta[0]["name"];
const name = this.$route.name;
this.$store.dispatch("commitToolBar", { name, detail, componentName });
}
}
};
</script>
<template>
<div id="app">
<CommonTools></CommonTools>
<transition name="fade-transform" mode="out-in">
<keep-alive :include="cachePath">
<router-view />
</keep-alive>
</transition>
</div>
</template>
<script>
import CommonTools from "@/components/commonTools.vue";
export default {
name: "App",
data() {
return {
};
},
components: {
CommonTools
},
computed: {
cachePath(el) {
//上面cachePage里的名字要和相应页面export里的name一致
return this.$store.state.cacheView;
}
},
methods: {
}
};
</script>
<style lang="scss">
</style>
// CSS 随意
.commonToolsWrap{
width: 100%;
// min-height: 64px;
background: #FFFFFF;
box-shadow: 0px 1px 4px 0px #E8E8E8;
margin-bottom: 16px;
padding-top:22px;
position: relative;
.commonTools{
display: flex;
align-items: flex-end;
width: 90%;
flex-flow: wrap;
padding-left: 5px;
.tabToolItem{
position: relative;
padding: 0px !important;
margin-left: 8px;
margin-top: 10px;
display: flex;
align-items: center;
justify-content: flex-start;
width: 180px;
height: 40px;
background: #FFFFFF;
box-shadow: -1px 0px 0px 0px #E9EBEF, 1px 0px 0px 0px #E9EBEF, 0px 1px 0px 0px #E9EBEF;
border-radius: 4px 4px 0px 0px;
padding-left: 10px !important;
cursor: pointer;
.txt{
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #1D1F24;
width: 140px;
font-size: 14px;
font-weight: 400;
color: #1D1F24;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.dot{
position: absolute;
content: '';
top: 0px;
left: 0px;
width: 180px;
height: 4px;
background: #2D82FF;
border-radius: 4px 4px 0px 0px;
}
.el-icon-close{
width: 14px;
height: 14px;
margin-left: 8px;
}
}
}
.tabToolItem:first-child{
}
}