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,
|
ElTabPane,
|
||||||
ElAvatar,
|
ElAvatar,
|
||||||
ElEmpty,
|
ElEmpty,
|
||||||
|
ElCollapse,
|
||||||
|
ElCollapseItem,
|
||||||
// 指令
|
// 指令
|
||||||
ElLoading,
|
ElLoading,
|
||||||
ElInfiniteScroll
|
ElInfiniteScroll
|
||||||
@ -106,7 +108,9 @@ const components = [
|
|||||||
ElTabs,
|
ElTabs,
|
||||||
ElTabPane,
|
ElTabPane,
|
||||||
ElAvatar,
|
ElAvatar,
|
||||||
ElEmpty
|
ElEmpty,
|
||||||
|
ElCollapse,
|
||||||
|
ElCollapseItem
|
||||||
];
|
];
|
||||||
// icon
|
// icon
|
||||||
export const iconComponents = [
|
export const iconComponents = [
|
||||||
|
@ -137,7 +137,7 @@ export const addAsyncRoutes = (arrRoutes: Array<RouteComponent>) => {
|
|||||||
// 创建路由实例
|
// 创建路由实例
|
||||||
export const router: Router = createRouter({
|
export const router: Router = createRouter({
|
||||||
history: createWebHashHistory(),
|
history: createWebHashHistory(),
|
||||||
routes: filterTree(ascending(constantRoutes)).concat(...remainingRouter),
|
routes: ascending(constantRoutes).concat(...remainingRouter),
|
||||||
scrollBehavior(to, from, savedPosition) {
|
scrollBehavior(to, from, savedPosition) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
if (savedPosition) {
|
if (savedPosition) {
|
||||||
|
@ -22,6 +22,18 @@ const tabsRouter = {
|
|||||||
showLink: true,
|
showLink: true,
|
||||||
i18n: 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 { positionType } from "./types";
|
||||||
import { storageLocal } from "/@/utils/storage";
|
import { storageLocal } from "/@/utils/storage";
|
||||||
|
|
||||||
|
interface Itag {
|
||||||
|
path: string;
|
||||||
|
parentPath: string;
|
||||||
|
name: string;
|
||||||
|
meta: any;
|
||||||
|
}
|
||||||
|
|
||||||
export const useMultiTagsStore = defineStore({
|
export const useMultiTagsStore = defineStore({
|
||||||
id: "pure-multiTags",
|
id: "pure-multiTags",
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@ -34,14 +41,44 @@ export const useMultiTagsStore = defineStore({
|
|||||||
this.getMultiTagsCache &&
|
this.getMultiTagsCache &&
|
||||||
storageLocal.setItem("responsive-tags", multiTags);
|
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) {
|
switch (mode) {
|
||||||
case "equal":
|
case "equal":
|
||||||
this.multiTags = value;
|
this.multiTags = value;
|
||||||
break;
|
break;
|
||||||
case "push":
|
case "push":
|
||||||
this.multiTags.push(value);
|
{
|
||||||
this.tagsCache(this.multiTags);
|
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;
|
break;
|
||||||
case "splice":
|
case "splice":
|
||||||
this.multiTags.splice(position?.startIndex, position?.length);
|
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>
|
<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>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
// .tabs-container {
|
.tabs-container {
|
||||||
// }
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
</style>
|
</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