mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-07 08:57:19 +08:00
feat: tabs operation view
This commit is contained in:
parent
8685092260
commit
3d34663eda
@ -41,6 +41,8 @@ import {
|
||||
ElTabPane,
|
||||
ElAvatar,
|
||||
ElEmpty,
|
||||
ElCollapse,
|
||||
ElCollapseItem,
|
||||
// 指令
|
||||
ElLoading,
|
||||
ElInfiniteScroll
|
||||
@ -106,7 +108,9 @@ const components = [
|
||||
ElTabs,
|
||||
ElTabPane,
|
||||
ElAvatar,
|
||||
ElEmpty
|
||||
ElEmpty,
|
||||
ElCollapse,
|
||||
ElCollapseItem
|
||||
];
|
||||
// icon
|
||||
export const iconComponents = [
|
||||
|
@ -137,7 +137,7 @@ export const addAsyncRoutes = (arrRoutes: Array<RouteComponent>) => {
|
||||
// 创建路由实例
|
||||
export const router: Router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes: filterTree(ascending(constantRoutes)).concat(...remainingRouter),
|
||||
routes: ascending(constantRoutes).concat(...remainingRouter),
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
return new Promise(resolve => {
|
||||
if (savedPosition) {
|
||||
|
@ -22,6 +22,18 @@ const tabsRouter = {
|
||||
showLink: true,
|
||||
i18n: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/tabs/detail/:id",
|
||||
name: "tabDetail",
|
||||
component: () => import("/@/views/tabs/tabDetail.vue"),
|
||||
meta: {
|
||||
title: "",
|
||||
showLink: false,
|
||||
i18n: false,
|
||||
dynamicLevel: 3,
|
||||
realPath: "/tabs/detail"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -4,6 +4,13 @@ import { getConfig } from "/@/config";
|
||||
import { positionType } from "./types";
|
||||
import { storageLocal } from "/@/utils/storage";
|
||||
|
||||
interface Itag {
|
||||
path: string;
|
||||
parentPath: string;
|
||||
name: string;
|
||||
meta: any;
|
||||
}
|
||||
|
||||
export const useMultiTagsStore = defineStore({
|
||||
id: "pure-multiTags",
|
||||
state: () => ({
|
||||
@ -34,14 +41,44 @@ export const useMultiTagsStore = defineStore({
|
||||
this.getMultiTagsCache &&
|
||||
storageLocal.setItem("responsive-tags", multiTags);
|
||||
},
|
||||
handleTags<T>(mode: string, value?: T, position?: positionType): any {
|
||||
handleTags<T>(
|
||||
mode: string,
|
||||
value?: T | Itag,
|
||||
position?: positionType
|
||||
): any {
|
||||
switch (mode) {
|
||||
case "equal":
|
||||
this.multiTags = value;
|
||||
break;
|
||||
case "push":
|
||||
{
|
||||
const tagVal = value as Itag;
|
||||
// 判断tag是否已存在:
|
||||
const tagHasExits = this.multiTags.some(tag => {
|
||||
return tag.path === tagVal?.path;
|
||||
});
|
||||
|
||||
if (tagHasExits) return;
|
||||
const meta = tagVal?.meta;
|
||||
const dynamicLevel = meta?.dynamicLevel ?? -1;
|
||||
if (dynamicLevel > 0) {
|
||||
// dynamicLevel动态路由可打开的数量
|
||||
const realPath = meta?.realPath ?? "";
|
||||
// 获取到已经打开的动态路由数, 判断是否大于dynamicLevel
|
||||
if (
|
||||
this.multiTags.filter(e => e.meta?.realPath ?? "" === realPath)
|
||||
.length >= dynamicLevel
|
||||
) {
|
||||
// 关闭第一个
|
||||
const index = this.multiTags.findIndex(
|
||||
item => item.meta?.realPath === realPath
|
||||
);
|
||||
index !== -1 && this.multiTags.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.multiTags.push(value);
|
||||
this.tagsCache(this.multiTags);
|
||||
}
|
||||
break;
|
||||
case "splice":
|
||||
this.multiTags.splice(position?.startIndex, position?.length);
|
||||
|
@ -1,10 +1,50 @@
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const activeName = ref("tag");
|
||||
|
||||
function toDetail(index: number) {
|
||||
useMultiTagsStoreHook().handleTags("push", {
|
||||
path: `/tabs/detail/${index}`,
|
||||
parentPath: route.matched[0].path,
|
||||
name: "tabDetail",
|
||||
meta: {
|
||||
title: `No.${index} - 详情信息`,
|
||||
showLink: false,
|
||||
i18n: false,
|
||||
dynamicLevel: 3,
|
||||
realPath: "/tabs/detail"
|
||||
}
|
||||
});
|
||||
router.push(`/tabs/detail/${index}`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tabs-container">111</div>
|
||||
<el-collapse v-model="activeName" class="tabs-container">
|
||||
<el-collapse-item
|
||||
title="标签页复用超出限制自动关闭(使用场景: 动态路由)"
|
||||
name="tag"
|
||||
>
|
||||
<el-button
|
||||
v-for="index in 6"
|
||||
:key="index"
|
||||
size="medium"
|
||||
@click="toDetail(index)"
|
||||
>
|
||||
打开{{ index }}详情页
|
||||
</el-button>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// .tabs-container {
|
||||
// }
|
||||
.tabs-container {
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
|
11
src/views/tabs/tabDetail.vue
Normal file
11
src/views/tabs/tabDetail.vue
Normal file
@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from "vue-router";
|
||||
const route = useRoute();
|
||||
const index = route.params?.id ?? -1;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>{{ index }} - 详情页内容在此</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
Loading…
x
Reference in New Issue
Block a user