vuex
import { debug } from "console";
import { createStore } from "vuex";
let availButtons = new Set();
export default createStore({
state: {
count: 0,
tabsList: [
{
path: "/",
name: "Profile",
meta: {
title: "首页",
},
},
],
keepAliveList: ["Profile"],
currentMenu: null,
menu: [],
buttons: availButtons,
},
mutations: {
setButtons(state, payload) {
state.buttons = payload.buttons;
},
selectMenu(state, val) {
console.log({ val });
if (val.path === "/") {
} else {
let result = state.tabsList.findIndex(
(item) => item.name === { ...val }.name
);
if (result === -1) {
state.tabsList.push({ ...val });
}
}
},
closeTab(state, val) {
let result = state.tabsList.findIndex(
(item) => item.name === val.name
);
state.tabsList.splice(result, 1);
state.keepAliveList.length = 0;
state.tabsList.forEach((item) => {
state.keepAliveList.push(item.name);
});
},
updateKeepList(state, val) {
let index = state.keepAliveList.findIndex(
(item: any) => item.name === val.name
);
if (index === -1) {
state.keepAliveList.push(val.name);
}
},
},
actions: {
},
getters: {
},
});
component/CommonTab.vue
<template>
<div class="tabs">
<el-tabs
v-model="currentName"
type="card"
editable
@tab-remove="handleTabsEdit"
@tab-click="handleTabClick"
>
<el-tab-pane
editable
:key="tag.meta.title"
v-for="tag in tags"
:label="tag.meta.title"
:name="tag.meta.title"
>
</el-tab-pane>
</el-tabs>
<div>{{ tags }}</div>
</div>
</template>
<script setup lang="ts">
import * as Utils from "@/utils";
import { mapState, mapMutations, useStore } from "vuex";
import { ref, reactive, onMounted, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
const currentName = ref("首页");
const tags = ref([]);
const store = useStore();
const router = useRouter();
const route = useRoute();
onMounted(() => {
tags.value = store.state.tabsList;
watch(
() => route.path,
() => {
currentName.value = route.meta.title as string;
},
{ immediate: true, deep: true }
);
});
function handleClose(tag: any, index: any) {
let length = tags.value.length - 1;
store.commit("closeTab", tag);
if (tag.name !== route.name) {
return;
}
if (index === length) {
router.push({ path: tags.value[index - 1].path });
} else {
router.push({ path: tags.value[index].path });
}
}
function changeMenu(item: any) {
let params = {
path: route.path,
name: route.name,
meta: {
title: route.meta.title,
},
};
store.commit("selectMenu", params);
}
function handleTabsEdit(targetName: any, action: any) {
let result = tags.value.findIndex(
(item: any) => item.meta.title === targetName
);
handleClose(tags.value[result], result);
}
function handleTabClick(tab: any) {
let result = tags.value.findIndex(
(item: any) => item.meta.title === currentName.value
);
changeMenu(tags.value[result]);
router.push({ path: tags.value[result].path });
}
</script>
<style lang="scss">
.tabs {
line-height: 50px;
margin-left: 18px;
text-align: left;
.el-tag {
margin-right: 5px;
cursor: pointer;
}
.dark {
background: #409eff;
border-color: #409eff !important;
color: #fff !important;
.el-tag__close {
color: #fff !important;
}
}
.plain {
background: #fff;
}
.el-tag {
color: #333;
.el-tag__close {
color: #333;
&:hover {
background: #cbcbce;
font-weight: bolder;
}
}
border-color: rgb(207, 204, 204);
}
}
</style>
vue3使用keepalive写法有变化。
<router-view v-slot="{ Component }">
<keep-alive :include="store.state.keepAliveList">
<component :is="Component" :key="route.path" />
</keep-alive>
</router-view>
菜单点击事件也有变化,获取的路由的上一次的路由,所以需要从菜单渲染中拿到数据。
与keepaliveList.keyValue一一对应。
const menuItemClick = (item: any) => {
const current = router;
let params = {
path: item.path,
name: item.routeName,
meta: {
title: item.name,
},
};
store.commit("selectMenu", params);
store.commit("updateKeepList", params);
};
|