mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-25 16:16:20 +08:00
feat: menu routing support opens in a new window (#4715)
This commit is contained in:
@@ -23,4 +23,15 @@ function openWindow(url: string, options: OpenWindowOptions = {}): void {
|
||||
window.open(url, target, features);
|
||||
}
|
||||
|
||||
export { openWindow };
|
||||
/**
|
||||
* 在新窗口中打开路由。
|
||||
* @param path
|
||||
*/
|
||||
function openRouteInNewWindow(path: string) {
|
||||
const { hash, origin } = location;
|
||||
const fullPath = path.startsWith('/') ? path : `/${path}`;
|
||||
const url = `${origin}${hash ? '/#' : ''}${fullPath}`;
|
||||
openWindow(url, { target: '_blank' });
|
||||
}
|
||||
|
||||
export { openRouteInNewWindow, openWindow };
|
||||
|
@@ -98,6 +98,10 @@ interface RouteMeta {
|
||||
* 菜单可以看到,但是访问会被重定向到403
|
||||
*/
|
||||
menuVisibleWithForbidden?: boolean;
|
||||
/**
|
||||
* 在新窗口打开
|
||||
*/
|
||||
openInNewWindow?: boolean;
|
||||
/**
|
||||
* 用于路由->菜单排序
|
||||
*/
|
||||
|
@@ -6,14 +6,12 @@ import { VbenIcon } from '../icon';
|
||||
interface Props extends BreadcrumbProps {}
|
||||
|
||||
defineOptions({ name: 'Breadcrumb' });
|
||||
withDefaults(defineProps<Props>(), {
|
||||
showIcon: false,
|
||||
});
|
||||
const { breadcrumbs, showIcon } = defineProps<Props>();
|
||||
|
||||
const emit = defineEmits<{ select: [string] }>();
|
||||
|
||||
function handleClick(path?: string) {
|
||||
if (!path) {
|
||||
function handleClick(index: number, path?: string) {
|
||||
if (!path || index === breadcrumbs.length - 1) {
|
||||
return;
|
||||
}
|
||||
emit('select', path);
|
||||
@@ -27,7 +25,10 @@ function handleClick(path?: string) {
|
||||
:key="`${item.path}-${item.title}-${index}`"
|
||||
>
|
||||
<li>
|
||||
<a href="javascript:void 0" @click.stop="handleClick(item.path)">
|
||||
<a
|
||||
href="javascript:void 0"
|
||||
@click.stop="handleClick(index, item.path)"
|
||||
>
|
||||
<span class="flex-center z-10 h-full">
|
||||
<VbenIcon
|
||||
v-if="showIcon"
|
||||
|
@@ -1,23 +1,25 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import { type RouteRecordNormalized, useRouter } from 'vue-router';
|
||||
|
||||
import { isHttpUrl, openWindow } from '@vben/utils';
|
||||
import { isHttpUrl, openRouteInNewWindow, openWindow } from '@vben/utils';
|
||||
|
||||
function useNavigation() {
|
||||
const router = useRouter();
|
||||
const routes = router.getRoutes();
|
||||
|
||||
const routeMetaMap = new Map<string, any>();
|
||||
const routeMetaMap = new Map<string, RouteRecordNormalized>();
|
||||
|
||||
routes.forEach((route) => {
|
||||
routeMetaMap.set(route.path, route.meta);
|
||||
routeMetaMap.set(route.path, route);
|
||||
});
|
||||
|
||||
const navigation = async (path: string) => {
|
||||
const route = routeMetaMap.get(path);
|
||||
const { openInNewWindow = false, query = {} } = route?.meta ?? {};
|
||||
if (isHttpUrl(path)) {
|
||||
openWindow(path, { target: '_blank' });
|
||||
} else if (openInNewWindow) {
|
||||
openRouteInNewWindow(path);
|
||||
} else {
|
||||
const meta = routeMetaMap.get(path);
|
||||
const query = meta?.query ?? {};
|
||||
await router.push({
|
||||
path,
|
||||
query,
|
||||
|
@@ -4,7 +4,7 @@ import type { Router, RouteRecordNormalized } from 'vue-router';
|
||||
import { toRaw } from 'vue';
|
||||
|
||||
import {
|
||||
openWindow,
|
||||
openRouteInNewWindow,
|
||||
startProgress,
|
||||
stopProgress,
|
||||
} from '@vben-core/shared/utils';
|
||||
@@ -290,11 +290,7 @@ export const useTabbarStore = defineStore('core-tabbar', {
|
||||
* @param tab
|
||||
*/
|
||||
async openTabInNewWindow(tab: TabDefinition) {
|
||||
const { hash, origin } = location;
|
||||
const path = tab.fullPath || tab.path;
|
||||
const fullPath = path.startsWith('/') ? path : `/${path}`;
|
||||
const url = `${origin}${hash ? '/#' : ''}${fullPath}`;
|
||||
openWindow(url, { target: '_blank' });
|
||||
openRouteInNewWindow(tab.fullPath || tab.path);
|
||||
},
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user