Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Commit

Permalink
fix: 面包屑导航和弹窗拖拽后宽度问题
Browse files Browse the repository at this point in the history
  • Loading branch information
buqiyuan committed Dec 31, 2021
1 parent b550a7a commit ae96559
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 77 deletions.
4 changes: 2 additions & 2 deletions .env.production
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# 只在生产模式中被载入

# base api
VITE_BASE_API = 'http://175.24.200.3:7001/admin/'
VITE_BASE_API = 'http://buqiyuan.site:7001/admin/'
VITE_BASE_SOCKET_PATH = '/ws-api'
VITE_BASE_SOCKET_NSP = 'ws://175.24.200.3:7002/admin'
VITE_BASE_SOCKET_NSP = 'ws://buqiyuan.site:7002/admin'

# 网站前缀
VITE_BASE_URL = /vite-vue3-admin/
Expand Down
6 changes: 6 additions & 0 deletions src/components/a-custom-modal/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
v-model:visible="visibleModel"
:maskClosable="false"
:getContainer="() => modalWrapRef"
:width="innerWidth || width"
@ok="emit('ok')"
@cancel="emit('cancel')"
>
Expand Down Expand Up @@ -65,6 +66,7 @@
const visibleModel = useVModel(props, 'visible');
const fullscreenModel = ref(props.fullscreen);
const innerWidth = ref('');
const cursorStyle = {
top: 'n-resize',
Expand Down Expand Up @@ -234,6 +236,7 @@
modalEl.style.width = event.clientX - iParentLeft + 'px';
modalEl.style.height = event.clientY - iParentTop + 'px';
}
innerWidth.value = modalEl.style.width;
};
const mouseup = () => {
Expand Down Expand Up @@ -276,6 +279,8 @@
.ant-modal {
position: fixed;
padding: 0;
min-height: 200px;
min-width: 200px;
.ant-modal-close {
top: 6px;
right: 6px;
Expand Down Expand Up @@ -308,6 +313,7 @@
min-width: 200px;
overflow: hidden;
.ant-modal-body {
flex: auto;
overflow: auto;
height: 100%;
}
Expand Down
81 changes: 66 additions & 15 deletions src/layout/header/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@
<component :is="collapsed ? MenuUnfoldOutlined : MenuFoldOutlined" />
</span>
<Breadcrumb>
<template v-for="(routeItem, rotueIndex) in $route.matched" :key="routeItem.name">
<template v-for="(routeItem, rotueIndex) in menus" :key="routeItem.name">
<Breadcrumb.Item>
<span>{{ getTitle(routeItem.meta.title) }}</span>
<template v-if="routeItem.children.length" #overlay>
<a-menu :selectedKeys="[$route.matched[rotueIndex + 1]?.name]" @click="clickMenuItem">
<template v-for="childItem in routeItem.children">
<a-menu-item v-if="!childItem.meta?.hideInMenu" :key="childItem.name">
<span>{{ getTitle(routeItem?.meta?.title) }}</span>
<template v-if="routeItem?.children?.length" #overlay>
<Menu :selectedKeys="[menus[rotueIndex + 1]?.name]">
<template v-for="childItem in routeItem?.children" :key="childItem.name">
<Menu.Item
v-if="!childItem.meta?.hideInMenu"
:key="childItem.name"
@click="clickMenuItem(childItem)"
>
<span>{{ getTitle(childItem.meta?.title) }}</span>
</a-menu-item>
</Menu.Item>
</template>
</a-menu>
</Menu>
</template>
</Breadcrumb.Item>
</template>
Expand Down Expand Up @@ -52,7 +56,7 @@

<script lang="tsx" setup>
import { ref, computed } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useRouter, useRoute, RouteRecordRaw } from 'vue-router';
import {
Layout,
message,
Expand Down Expand Up @@ -92,14 +96,61 @@
const router = useRouter();
const route = useRoute();
const userInfo = computed(() => userStore.userInfo);
const menus = computed(() => {
console.log('route', route, userStore.menus);
if (route.meta?.namePath) {
let children = userStore.menus;
const paths = route.meta?.namePath?.map((item) => {
const a = children.find((n) => n.name === item);
children = a?.children || [];
return a;
});
return [
{
name: '__index',
meta: {
title: '首页',
},
children: userStore.menus,
},
...paths,
];
}
return route.matched;
});

const findLastChild = (route?: RouteRecordRaw) => {
if (typeof route?.redirect === 'object') {
const redirectValues = Object.values(route.redirect);
if (route?.children?.length) {
const target = route.children.find((n) =>
redirectValues.some((m) => [n.name, n.path, n.meta?.fullPath].some((v) => v === m)),
);
return findLastChild(target);
}
return redirectValues.find((n) => typeof n === 'string');
} else if (typeof route?.redirect === 'string') {
if (route?.children?.length) {
const target = route.children.find((n) =>
[n.name, n.path, n.meta?.fullPath].some((m) => m === route?.redirect),
);
return findLastChild(target);
}
return route?.redirect;
}
return route;
};

// 点击菜单
const clickMenuItem = ({ key }) => {
if (key === route.name) return;
if (/http(s)?:/.test(key)) {
window.open(key);
} else {
router.push({ name: key });
const clickMenuItem = (menuItem: RouteRecordRaw) => {
const lastChild = findLastChild(menuItem);
console.log('lastChild', menuItem, lastChild);

if (lastChild?.name === route.name) return;
if (/http(s)?:/.test(lastChild?.name)) {
window.open(lastChild?.name);
} else if (lastChild?.name) {
router.push({ name: lastChild.name });
}
};

Expand Down
14 changes: 8 additions & 6 deletions src/layout/menu/menu.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
<template>
<a-menu
<Menu
v-model:open-keys="state.openKeys"
v-model:selected-keys="state.selectedKeys"
mode="inline"
theme="dark"
:inline-collapsed="props.collapsed"
:collapsed="props.collapsed"
collapsible
class="menu-container"
@click="clickMenuItem"
>
<template v-for="item in menus" :key="item.name">
<menu-item :menu-info="item" />
<MenuItem :menu-info="item" />
</template>
</a-menu>
</Menu>
</template>

<script setup lang="ts">
import { reactive, computed, watch } from 'vue';
import { Menu } from 'ant-design-vue';
import MenuItem from './menu-item.vue';
import { useUserStore } from '@/store/modules/user';
import { useRoute, useRouter } from 'vue-router';
Expand Down Expand Up @@ -43,9 +45,9 @@
const meta = currentRoute.meta;
if (meta?.activeMenu) {
const targetMenu = getTargetMenuByActiveMenuName(meta.activeMenu);
return targetMenu?.meta?.keyPath ?? meta?.activeMenu;
return targetMenu?.meta?.namePath ?? [meta?.activeMenu];
}
return currentRoute.meta?.keyPath ?? currentRoute.matched.slice(1).map((n) => n.name);
return currentRoute.meta?.namePath ?? currentRoute.matched.slice(1).map((n) => n.name);
};
const state = reactive({
Expand Down
2 changes: 1 addition & 1 deletion src/layout/tabs/tabs-view.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
<div class="tabs-view-content">
<router-view v-slot="{ Component }">
<template v-if="Component">
<transition name="zoom-fade" mode="out-in" appear>
<transition name="fade-transform" mode="out-in" appear>
<keep-alive :include="keepAliveComponents">
<suspense>
<component :is="Component" :key="route.fullPath" />
Expand Down
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'virtual:windi.css';
import 'virtual:windi-devtools';
import 'virtual:svg-icons-register';
// 全局公共样式
import '@/styles/index.less';

import { createApp } from 'vue';
import App from './App.vue';
Expand Down
4 changes: 3 additions & 1 deletion src/router/asyncModules/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export default {
import('@/views/shared/demos/form/rule-form/index.vue'), // 验证表单
'views/shared/demos/icons/Iconfont.vue': () => import('@/views/shared/demos/icons/Iconfont.vue'), // 自定义图标
[`views/${prefix}tables/wzry-table/index.vue`]: () =>
import('@/views/shared/demos/tables/wzry-table/index.vue'), // 合计表格
import('@/views/shared/demos/tables/wzry-table/index.vue'), // wzry
[`views/${prefix}tables/lol-table/index.vue`]: () =>
import('@/views/shared/demos/tables/lol-table/index.vue'), // lol
'views/shared/demos/button.vue': () => import('@/views/shared/demos/button.vue'), // 自定义按钮
'views/shared/demos/custom-modal.vue': () => import('@/views/shared/demos/custom-modal.vue'), // 自定义模态框
};
40 changes: 27 additions & 13 deletions src/router/generator-router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Result } from 'ant-design-vue';
import { type RouteRecordRaw } from 'vue-router';
import RouterView from '@/layout/routerView/index.vue';
import { isUrl } from '@/utils/is';
import { uniqueSlash } from '@/utils/urlUtils';
import { constantRouterComponents } from '@/router/asyncModules';
import NotFound from '@/views/shared/error/404.vue';
import router, { routes } from '.';
Expand All @@ -16,20 +17,20 @@ const endRoutes: RouteRecordRaw[] = [...shared, errorRoutes, notFound];
export function filterAsyncRoute(
routes: API.Menu[],
parentRoute: API.Menu | null = null,
lastKeyPath: string[] = [],
lastNamePath: string[] = [],
): RouteRecordRaw[] {
return routes
.filter((item) => item.type !== 2 && item.isShow && item.parentId == parentRoute?.id)
.map((item) => {
const { router, viewPath, name, icon, keepalive } = item;
let fullPath = '';
const pathPrefix = lastKeyPath.slice(-1)[0] || '';
const pathPrefix = lastNamePath.slice(-1)[0] || '';
if (isUrl(router)) {
fullPath = router;
} else {
fullPath = router.startsWith('/') ? router : '/' + router;
fullPath = router.startsWith(pathPrefix) ? fullPath : pathPrefix + fullPath;
fullPath = [...new Set(fullPath.split('/'))].join('/');
fullPath = [...new Set(uniqueSlash(fullPath).split('/'))].join('/');
}
let realRoutePath = router;
if (parentRoute) {
Expand All @@ -48,14 +49,14 @@ export function filterAsyncRoute(
title: name,
perms: [],
icon: icon,
keyPath: lastKeyPath.concat(fullPath),
namePath: lastNamePath.concat(fullPath),
keepAlive: keepalive,
},
};

if (item.type === 0) {
// 如果是目录
const children = filterAsyncRoute(routes, item, lastKeyPath.concat(fullPath));
const children = filterAsyncRoute(routes, item, lastNamePath.concat(fullPath));
if (children?.length) {
route.component = RouterView;
route.children = children;
Expand Down Expand Up @@ -100,20 +101,21 @@ export const generatorDynamicRouter = (asyncMenus: API.Menu[]) => {
const routeList = filterAsyncRoute(asyncMenus);
const layout = routes.find((item) => item.name == 'Layout')!;
// console.log(routeList, '根据后端返回的权限路由生成');
generatorKeyPath(common);
// 给公共路由添加namePath
generatorNamePath(common);
const menus = [...common, ...routeList];
layout.children = menus;
const removeRoute = router.addRoute(layout);
// 获取所有没有包含children的路由,上面addRoute的时候,vue-router已经帮我们拍平了所有路由
const filterRoutes = router.getRoutes().filter((item) => !item.children.length);
// console.log('所有路由', filterRoutes);
// 清空所有路由
removeRoute();
layout.children = filterRoutes;
// 重新添加拍平后的路由
router.addRoute(layout);
// 追加末尾路由
endRoutes.forEach((item) => router.addRoute(item));
// console.log('所有路由', router.getRoutes());
return {
menus: menus,
routes: layout.children,
Expand All @@ -129,19 +131,31 @@ export const generatorDynamicRouter = (asyncMenus: API.Menu[]) => {

/**
* 主要方便于控制a-menu的open-keys,即控制左侧菜单应当展开哪些菜单
* @param {RouteRecordRaw[]} routes 需要添加keyPath的路由
* @param {string[]} keyPath
* @param {RouteRecordRaw[]} routes 需要添加namePath的路由
* @param {string[]} namePath
*/
export const generatorKeyPath = (routes: RouteRecordRaw[], keyPath?: string[]) => {
export const generatorNamePath = (
routes: RouteRecordRaw[],
namePath?: string[],
parent?: RouteRecordRaw,
) => {
routes.forEach((item) => {
if (item.children?.length) {
if (item.meta && typeof item.name === 'string') {
item.meta.keyPath = Array.isArray(keyPath) ? keyPath.concat(item.name) : [item.name];
generatorKeyPath(item.children, item.meta.keyPath);
item.meta.namePath = Array.isArray(namePath) ? namePath.concat(item.name) : [item.name];
item.meta.fullPath = parent?.meta?.fullPath
? [parent.meta.fullPath, item.path].join('/')
: item.path;
item.meta.fullPath = uniqueSlash(item.meta.fullPath);
generatorNamePath(item.children, item.meta.namePath, item);
}
} else {
if (item.meta && typeof item.name === 'string') {
item.meta.keyPath = Array.isArray(keyPath) ? keyPath.concat(item.name) : [item.name];
item.meta.namePath = Array.isArray(namePath) ? namePath.concat(item.name) : [item.name];
item.meta.fullPath = parent?.meta?.fullPath
? [parent.meta.fullPath, item.path].join('/')
: item.path;
item.meta.fullPath = uniqueSlash(item.meta.fullPath);
}
}
});
Expand Down
Loading

0 comments on commit ae96559

Please sign in to comment.