feat: tabs operation view

This commit is contained in:
lrl 2021-11-28 15:06:22 +08:00
parent 8685092260
commit 3d34663eda
6 changed files with 113 additions and 9 deletions

View File

@ -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 = [

View File

@ -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) {

View File

@ -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"
}
} }
] ]
}; };

View File

@ -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);

View File

@ -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>

View 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>