You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

180 lines
5.4 KiB

import html from "html";
import { defineAsyncComponent, ref, nextTick, getCurrentInstance } from "vue";
import { useRoute, onBeforeRouteUpdate, useRouter } from "vue-router";
import { useAppStore } from "../store/index.js";
export default {
components: { SvgIcon: defineAsyncComponent(() => import("../components/icon/index.js")) },
template: html`<el-tabs
v-model="model"
type="border-card"
class="router-tab"
@tab-remove="remove"
@tab-click="onClick"
>
<template v-for="(item, index) in appStore.routes" :key="item.fullPath">
<el-tab-pane v-model="item.fullPath" :name="item.fullPath" :closable="appStore.routes.length > 1">
<template #label>
<el-dropdown
:ref="(el) => setRef(index, el)"
class="h-full"
trigger="contextmenu"
@visible-change="showContextMenu(index, $event)"
>
<span class="inline-flex items-center">
<el-icon><svg-icon v-if="item.meta.icon" :name="item.meta.icon" /></el-icon>
{{ item.meta?.title ?? item.fullPath }}
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="refresh(index)">
<el-icon><ep-refresh /></el-icon><span>刷新</span>
</el-dropdown-item>
<el-dropdown-item :disabled="index === 0" @click="removeLeft(index)">
<el-icon><ep-back /></el-icon><span>关闭左侧</span>
</el-dropdown-item>
<el-dropdown-item :disabled="index === appStore.routes.length - 1" @click="removeRight(index)">
<el-icon><ep-right /></el-icon><span>关闭右侧</span>
</el-dropdown-item>
<el-dropdown-item
:disabled="index === 0 && index === appStore.routes.length - 1"
@click="removeOthers(index)"
><el-icon><ep-switch /></el-icon><span>关闭其他</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-tab-pane>
</template>
</el-tabs>`,
styles: html`
<style>
.router-tab {
box-sizing: border-box;
height: 40px !important;
background-color: var(--el-fill-color-blank);
border-width: 0 !important;
}
.router-tab .el-tabs__item {
padding: 13px !important;
border-bottom-width: 0;
}
.router-tab .el-tabs__content {
display: none;
}
.router-tab .el-icon {
margin-right: 5px;
}
</style>
`,
setup() {
const appStore = useAppStore();
const itemRefs = ref([]);
const currentRoute = useRoute();
const router = useRouter();
const model = ref(currentRoute.fullPath);
onBeforeRouteUpdate((to) => {
model.value = to.fullPath;
});
const setRef = (index, el) => {
if (el) {
itemRefs.value[index] = el;
} else {
itemRefs.value.splice(index, 1);
}
};
const showContextMenu = (index, show) => {
if (show) {
itemRefs.value.forEach((item, i) => {
if (i !== index) {
item?.handleClose();
}
});
}
};
const refresh = (index) => {
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath);
const route = appStore.routes[index];
if (index !== currentIndex) {
router.push({ path: route.fullPath });
}
appStore.isRefreshing = true;
nextTick(() => {
appStore.isRefreshing = false;
});
};
const deleteItem = (start, end) => {
appStore.routes.splice(start, end);
const vue = getCurrentInstance();
console.log(vue);
};
const remove = (name) => {
if (appStore.routes.length > 1) {
const index = appStore.routes.findIndex((o) => o.fullPath === name);
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath);
deleteItem(index, 1);
if (index === currentIndex) {
if (appStore.routes[index]) {
router.push(appStore.routes[index]);
} else {
router.push(appStore.routes[index - 1]);
}
}
}
};
const removeLeft = (index) => {
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath);
const route = appStore.routes[index];
deleteItem(0, index);
if (currentIndex < index) {
router.push(route);
}
};
const removeRight = (index) => {
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath);
deleteItem(index + 1, appStore.routes.length - index);
if (currentIndex > index) {
router.push(appStore.routes[index]);
}
};
const removeOthers = (index) => {
removeRight(index);
removeLeft(index);
if (appStore.routes[0].fullPath !== currentRoute.fullPath) {
router.push(appStore.routes[0]);
}
};
const onClick = (context) => {
if (!context.active) {
router.push(context.props.name);
}
};
return {
model,
appStore,
itemRefs,
onBeforeRouteUpdate,
setRef,
showContextMenu,
refresh,
remove,
removeLeft,
removeRight,
removeOthers,
onClick,
};
},
};