feat: 菜单跳转,关联tags栏
This commit is contained in:
parent
7ff3b00d0e
commit
77ee7ba1af
@ -1,35 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-layout-content class="content">
|
<a-layout-content class="content">
|
||||||
<Tabs />
|
<Tabs />
|
||||||
<a-scrollbar style="height: 100%; overflow: auto" outer-class="scrollbar">
|
<a-scrollbar style="height: 100%; overflow: auto" outer-class="scrollbar">
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="main_box"></div>
|
<router-view />
|
||||||
</div>
|
</div>
|
||||||
</a-scrollbar>
|
</a-scrollbar>
|
||||||
</a-layout-content>
|
</a-layout-content>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Tabs from "@/layout/components/Tabs/index.vue";
|
import Tabs from "@/layout/components/Tabs/index.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.content {
|
.content {
|
||||||
height: calc(100vh - 60px - 30px); // 动态切类名-去掉footer
|
height: calc(100vh - 60px - 30px); // 动态切类名-去掉footer
|
||||||
}
|
}
|
||||||
.scrollbar {
|
.scrollbar {
|
||||||
height: calc(100% - 40px);
|
height: calc(100% - 40px);
|
||||||
}
|
}
|
||||||
.main {
|
.main {
|
||||||
padding: $padding;
|
padding: $padding;
|
||||||
.main_box {
|
}
|
||||||
height: 1000px;
|
// 修改左侧滚动条宽度
|
||||||
background: #eee;
|
:deep(.arco-scrollbar-thumb-direction-vertical .arco-scrollbar-thumb-bar) {
|
||||||
}
|
width: 4px;
|
||||||
}
|
margin-left: 8px;
|
||||||
// 修改左侧滚动条宽度
|
}
|
||||||
:deep(.arco-scrollbar-thumb-direction-vertical .arco-scrollbar-thumb-bar) {
|
</style>
|
||||||
width: 4px;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-menu breakpoint="xl" :collapsed="collapsed">
|
<a-menu breakpoint="xl" :collapsed="collapsed" @menu-item-click="onMenuItem">
|
||||||
<MenuItem :route-tree="routeTree" />
|
<MenuItem :route-tree="routeTree" />
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</template>
|
</template>
|
||||||
@ -9,13 +9,25 @@ import MenuItem from "@/layout/components/Menu/menu-item.vue";
|
|||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import { useThemeConfig } from "@/store/theme-config";
|
import { useThemeConfig } from "@/store/theme-config";
|
||||||
import { useRoutesListStore } from "@/store/route-list";
|
import { useRoutesListStore } from "@/store/route-list";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
const router = useRouter();
|
||||||
const routerStore = useRoutesListStore();
|
const routerStore = useRoutesListStore();
|
||||||
const { routeTree } = storeToRefs(routerStore);
|
const { routeTree, routeList } = storeToRefs(routerStore);
|
||||||
const themeStore = useThemeConfig();
|
const themeStore = useThemeConfig();
|
||||||
const { collapsed } = storeToRefs(themeStore);
|
const { collapsed } = storeToRefs(themeStore);
|
||||||
|
|
||||||
console.log("路由树", routeTree.value);
|
console.log("路由树", routeTree.value);
|
||||||
|
|
||||||
|
const onMenuItem = (key: string) => {
|
||||||
|
let find = routeList.value.find((item: Menu.MenuOptions) => item.name === key);
|
||||||
|
console.log("当前", find);
|
||||||
|
if (find) {
|
||||||
|
routerStore.setTagsList(find);
|
||||||
|
router.push(find.path);
|
||||||
|
} else {
|
||||||
|
router.push("/404");
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<template #title>{{ item.meta.title }}</template>
|
<template #title>{{ item.meta.title }}</template>
|
||||||
<MenuItem :route-tree="item.children" />
|
<MenuItem :route-tree="item.children" />
|
||||||
</a-sub-menu>
|
</a-sub-menu>
|
||||||
<a-menu-item v-else :key="item.name">
|
<a-menu-item v-else :key="item?.name">
|
||||||
<template #icon v-if="item.meta.svgIcon || item.meta.icon">
|
<template #icon v-if="item.meta.svgIcon || item.meta.icon">
|
||||||
<IconCommon :svg-icon="item.meta.svgIcon" :icon="item.meta.icon" />
|
<IconCommon :svg-icon="item.meta.svgIcon" :icon="item.meta.icon" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,122 +1,129 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
<a-tabs
|
<a-tabs :editable="true" :hide-content="true" size="medium" type="line" @delete="handleDelete">
|
||||||
:editable="true"
|
<a-tab-pane v-for="item of tagsList" :key="item.name" :title="item.meta.title" :closable="!item.meta.isAffix" />
|
||||||
:hide-content="true"
|
</a-tabs>
|
||||||
size="medium"
|
<div class="tabs_setting">
|
||||||
type="line"
|
<a-dropdown trigger="hover">
|
||||||
show-add-button
|
<div class="setting"><icon-loop :size="18" /></div>
|
||||||
@add="handleAdd"
|
<template #content>
|
||||||
@delete="handleDelete"
|
<a-doption>
|
||||||
>
|
<template #icon><icon-refresh /></template>
|
||||||
<a-tab-pane v-for="(item, index) of data" :key="item.key" :title="item.title" :closable="index !== 2" />
|
<template #default>刷新</template>
|
||||||
</a-tabs>
|
</a-doption>
|
||||||
<div class="tabs_setting">
|
<a-doption>
|
||||||
<a-dropdown trigger="hover">
|
<template #icon><icon-left /></template>
|
||||||
<div class="setting"><icon-loop :size="18" /></div>
|
<template #default>关闭左侧</template>
|
||||||
<template #content>
|
</a-doption>
|
||||||
<a-doption>
|
<a-doption>
|
||||||
<template #icon><icon-refresh /></template>
|
<template #icon><icon-right /></template>
|
||||||
<template #default>刷新</template>
|
<template #default>关闭右侧</template>
|
||||||
</a-doption>
|
</a-doption>
|
||||||
<a-doption>
|
<a-doption>
|
||||||
<template #icon><icon-left /></template>
|
<template #icon><icon-close /></template>
|
||||||
<template #default>关闭左侧</template>
|
<template #default>关闭其它</template>
|
||||||
</a-doption>
|
</a-doption>
|
||||||
<a-doption>
|
<a-doption>
|
||||||
<template #icon><icon-right /></template>
|
<template #icon><icon-close-circle /></template>
|
||||||
<template #default>关闭右侧</template>
|
<template #default>全部关闭</template>
|
||||||
</a-doption>
|
</a-doption>
|
||||||
<a-doption>
|
</template>
|
||||||
<template #icon><icon-close /></template>
|
</a-dropdown>
|
||||||
<template #default>关闭其它</template>
|
</div>
|
||||||
</a-doption>
|
</div>
|
||||||
<a-doption>
|
</template>
|
||||||
<template #icon><icon-close-circle /></template>
|
|
||||||
<template #default>全部关闭</template>
|
<script setup lang="ts">
|
||||||
</a-doption>
|
import { storeToRefs } from "pinia";
|
||||||
</template>
|
import { useRoutesListStore } from "@/store/route-list";
|
||||||
</a-dropdown>
|
const routerStore = useRoutesListStore();
|
||||||
</div>
|
const { tagsList } = storeToRefs(routerStore);
|
||||||
</div>
|
|
||||||
</template>
|
watch(
|
||||||
|
tagsList.value,
|
||||||
<script setup lang="ts">
|
newV => {
|
||||||
let count = 5;
|
console.log("tagsList", newV);
|
||||||
const data = ref([
|
},
|
||||||
{
|
{ flush: "post" }
|
||||||
key: "1",
|
);
|
||||||
title: "Tab 1",
|
|
||||||
content: "Content of Tab Panel 1"
|
// let count = 5;
|
||||||
},
|
// const data = ref([
|
||||||
{
|
// {
|
||||||
key: "2",
|
// key: "1",
|
||||||
title: "Tab 2",
|
// title: "Tab 1",
|
||||||
content: "Content of Tab Panel 2"
|
// content: "Content of Tab Panel 1"
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
key: "3",
|
// key: "2",
|
||||||
title: "Tab 3",
|
// title: "Tab 2",
|
||||||
content: "Content of Tab Panel 3"
|
// content: "Content of Tab Panel 2"
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
key: "4",
|
// key: "3",
|
||||||
title: "Tab 4",
|
// title: "Tab 3",
|
||||||
content: "Content of Tab Panel 4"
|
// content: "Content of Tab Panel 3"
|
||||||
}
|
// },
|
||||||
]);
|
// {
|
||||||
|
// key: "4",
|
||||||
const handleAdd = () => {
|
// title: "Tab 4",
|
||||||
const number = count++;
|
// content: "Content of Tab Panel 4"
|
||||||
data.value = data.value.concat({
|
// }
|
||||||
key: `${number}`,
|
// ]);
|
||||||
title: `New Tab ${number}`,
|
|
||||||
content: `Content of New Tab Panel ${number}`
|
// const handleAdd = () => {
|
||||||
});
|
// const number = count++;
|
||||||
};
|
// data.value = data.value.concat({
|
||||||
const handleDelete = (key: any) => {
|
// key: `${number}`,
|
||||||
data.value = data.value.filter(item => item.key !== key);
|
// title: `New Tab ${number}`,
|
||||||
};
|
// content: `Content of New Tab Panel ${number}`
|
||||||
</script>
|
// });
|
||||||
|
// };
|
||||||
<style lang="scss" scoped>
|
const handleDelete = (key: any) => {
|
||||||
.tabs {
|
console.log("关闭tags", key);
|
||||||
height: 40px;
|
|
||||||
box-sizing: border-box;
|
// data.value = data.value.filter(item => item.key !== key);
|
||||||
border-bottom: $border-1 solid $color-border-2;
|
};
|
||||||
display: flex;
|
</script>
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
<style lang="scss" scoped>
|
||||||
.tabs_setting {
|
.tabs {
|
||||||
margin: 0 0 0 $margin;
|
height: 40px;
|
||||||
.setting {
|
box-sizing: border-box;
|
||||||
margin-right: $margin;
|
border-bottom: $border-1 solid $color-border-2;
|
||||||
color: $color-text-2;
|
display: flex;
|
||||||
}
|
justify-content: space-between;
|
||||||
}
|
align-items: center;
|
||||||
}
|
.tabs_setting {
|
||||||
:deep(.arco-tabs-nav-tab) {
|
margin: 0 0 0 $margin;
|
||||||
// 移入展示关闭icon
|
.setting {
|
||||||
.arco-tabs-tab-closable {
|
margin-right: $margin;
|
||||||
svg {
|
color: $color-text-2;
|
||||||
width: 0px;
|
}
|
||||||
transition: all 0.2s;
|
}
|
||||||
}
|
}
|
||||||
&:hover {
|
:deep(.arco-tabs-nav-tab) {
|
||||||
svg {
|
// 移入展示关闭icon
|
||||||
width: 1em;
|
.arco-tabs-tab-closable {
|
||||||
}
|
svg {
|
||||||
}
|
width: 0px;
|
||||||
}
|
transition: all 0.2s;
|
||||||
// 消除tab移入的背景色
|
}
|
||||||
&:hover .arco-tabs-tab-title::before {
|
&:hover {
|
||||||
background: unset;
|
svg {
|
||||||
}
|
width: 1em;
|
||||||
}
|
}
|
||||||
// 消除tabs底部边线
|
}
|
||||||
:deep(.arco-tabs-nav) {
|
}
|
||||||
&::before {
|
// 消除tab移入的背景色
|
||||||
background: unset;
|
&:hover .arco-tabs-tab-title::before {
|
||||||
}
|
background: unset;
|
||||||
}
|
}
|
||||||
</style>
|
}
|
||||||
|
// 消除tabs底部边线
|
||||||
|
:deep(.arco-tabs-nav) {
|
||||||
|
&::before {
|
||||||
|
background: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -39,7 +39,7 @@ export async function initSetRouter() {
|
|||||||
export function setCacheName(flattenedArray: any) {
|
export function setCacheName(flattenedArray: any) {
|
||||||
const store = useRoutesListStore(pinia);
|
const store = useRoutesListStore(pinia);
|
||||||
const cacheName = flattenedArray.map((item: any) => item.name);
|
const cacheName = flattenedArray.map((item: any) => item.name);
|
||||||
store.setrouteNames(cacheName); // 缓存路由name
|
store.setRouteNames(cacheName); // 缓存路由name
|
||||||
store.setRouteList(flattenedArray); // 缓存路由
|
store.setRouteList(flattenedArray); // 缓存路由
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -191,16 +191,6 @@ export const staticRoutes = [
|
|||||||
* @link 参考:https://router.vuejs.org/zh/guide/essentials/history-mode.html#netlify
|
* @link 参考:https://router.vuejs.org/zh/guide/essentials/history-mode.html#netlify
|
||||||
*/
|
*/
|
||||||
export const notFoundAndNoPower = [
|
export const notFoundAndNoPower = [
|
||||||
// 未找到页面的时候跳转该页面
|
|
||||||
{
|
|
||||||
path: "/:path(.*)*",
|
|
||||||
name: "notFound",
|
|
||||||
component: () => import("@/views/error/404.vue"),
|
|
||||||
meta: {
|
|
||||||
title: "notFound",
|
|
||||||
isHide: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/401",
|
path: "/401",
|
||||||
name: "noPower",
|
name: "noPower",
|
||||||
@ -209,5 +199,14 @@ export const notFoundAndNoPower = [
|
|||||||
title: "notFound",
|
title: "notFound",
|
||||||
isHide: true
|
isHide: true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/:path(.*)*", // 匹配任意路由,兜底,未找到页面的时候跳转该页面
|
||||||
|
name: "notFound",
|
||||||
|
component: () => import("@/views/error/404.vue"),
|
||||||
|
meta: {
|
||||||
|
title: "notFound",
|
||||||
|
isHide: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@ -4,13 +4,14 @@ import { defineStore } from "pinia";
|
|||||||
* 路由列表
|
* 路由列表
|
||||||
* @methods setRouteTree 设置路由树
|
* @methods setRouteTree 设置路由树
|
||||||
* @methods setRoutesList 设置路由一维数据
|
* @methods setRoutesList 设置路由一维数据
|
||||||
* @methods setrouteNames 设置路由名称集合
|
* @methods setRouteNames 设置路由名称集合
|
||||||
*/
|
*/
|
||||||
export const useRoutesListStore = defineStore("routeList", {
|
export const useRoutesListStore = defineStore("routeList", {
|
||||||
state: (): any => ({
|
state: (): any => ({
|
||||||
routeTree: [], // 路由树
|
routeTree: [], // 路由树
|
||||||
routeList: [], // 路由数据
|
routeList: [], // 路由数据-一维
|
||||||
routeNames: [] // 路由名称
|
routeNames: [], // 路由名称
|
||||||
|
tagsList: [] // 标签页数据
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
setRouteTree(data: any) {
|
setRouteTree(data: any) {
|
||||||
@ -19,8 +20,14 @@ export const useRoutesListStore = defineStore("routeList", {
|
|||||||
setRouteList(data: any) {
|
setRouteList(data: any) {
|
||||||
this.routeList = data;
|
this.routeList = data;
|
||||||
},
|
},
|
||||||
setrouteNames(data: Array<string>) {
|
setRouteNames(data: Array<string>) {
|
||||||
this.routeNames = data;
|
this.routeNames = data;
|
||||||
|
},
|
||||||
|
setTagsList(data: Menu.MenuOptions) {
|
||||||
|
let isExist = this.tagsList.some((item: Menu.MenuOptions) => item.name === data.name);
|
||||||
|
if (!isExist) {
|
||||||
|
this.tagsList.push(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user