Skip to content

Commit

Permalink
feat: menu routing support opens in a new window (#4715)
Browse files Browse the repository at this point in the history
  • Loading branch information
anncwb authored Oct 22, 2024
1 parent f60796f commit 23768ea
Show file tree
Hide file tree
Showing 13 changed files with 315 additions and 190 deletions.
4 changes: 4 additions & 0 deletions docs/src/en/guide/essentials/route.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,10 @@ interface RouteMeta {
* The menu is visible, but access will be redirected to 403
*/
menuVisibleWithForbidden?: boolean;
/**
* Open in a new window
*/
openInNewWindow?: boolean;
/**
* Used for route->menu sorting
*/
Expand Down
11 changes: 11 additions & 0 deletions docs/src/guide/essentials/route.md
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,10 @@ interface RouteMeta {
* 菜单可以看到,但是访问会被重定向到403
*/
menuVisibleWithForbidden?: boolean;
/**
* 在新窗口打开
*/
openInNewWindow?: boolean;
/**
* 用于路由->菜单排序
*/
Expand Down Expand Up @@ -539,6 +543,13 @@ interface RouteMeta {

用于配置页面在菜单可以看到,但是访问会被重定向到403。

### openInNewWindow

- 类型:`boolean`
- 默认值:`false`

设置为 `true` 时,会在新窗口打开页面。

### order

- 类型:`number`
Expand Down
13 changes: 12 additions & 1 deletion packages/@core/base/shared/src/utils/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
4 changes: 4 additions & 0 deletions packages/@core/base/typings/src/vue-router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ interface RouteMeta {
* 菜单可以看到,但是访问会被重定向到403
*/
menuVisibleWithForbidden?: boolean;
/**
* 在新窗口打开
*/
openInNewWindow?: boolean;
/**
* 用于路由->菜单排序
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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"
Expand Down
14 changes: 8 additions & 6 deletions packages/effects/layouts/src/basic/menu/use-navigation.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
8 changes: 2 additions & 6 deletions packages/stores/src/modules/tabbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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);
},

/**
Expand Down
3 changes: 2 additions & 1 deletion playground/src/locales/langs/en-US/demos.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"tabDetail": "Tab Detail Page",
"fullScreen": "FullScreen",
"clipboard": "Clipboard",
"menuWithQuery": "Menu With Query"
"menuWithQuery": "Menu With Query",
"openInNewWindow": "Open in New Window"
},
"breadcrumb": {
"navigation": "Breadcrumb Navigation",
Expand Down
3 changes: 2 additions & 1 deletion playground/src/locales/langs/zh-CN/demos.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"tabDetail": "标签详情页",
"fullScreen": "全屏",
"clipboard": "剪贴板",
"menuWithQuery": "带参菜单"
"menuWithQuery": "带参菜单",
"openInNewWindow": "新窗口打开"
},
"breadcrumb": {
"navigation": "面包屑导航",
Expand Down
13 changes: 12 additions & 1 deletion playground/src/router/routes/modules/demos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ const routes: RouteRecordRaw[] = [
import('#/views/demos/features/full-screen/index.vue'),
meta: {
icon: 'lucide:fullscreen',
title: $t('demos.features.title'),
title: $t('demos.features.fullScreen'),
},
},
{
Expand All @@ -200,6 +200,17 @@ const routes: RouteRecordRaw[] = [
title: $t('demos.features.menuWithQuery'),
},
},
{
name: 'NewWindowDemo',
path: '/demos/new-window',
component: () =>
import('#/views/demos/features/new-window/index.vue'),
meta: {
icon: 'lucide:app-window',
openInNewWindow: true,
title: $t('demos.features.openInNewWindow'),
},
},
{
name: 'VueQueryDemo',
path: '/demos/features/vue-query',
Expand Down
11 changes: 11 additions & 0 deletions playground/src/views/demos/features/new-window/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts" setup>
import { Fallback } from '@vben/common-ui';
</script>

<template>
<Fallback
description="当前页面已在新窗口内打开"
status="coming-soon"
title="新窗口打开页面"
/>
</template>
Loading

0 comments on commit 23768ea

Please sign in to comment.