From a441dcebaedc2d2dcf954a33c9d7e57934ce74d4 Mon Sep 17 00:00:00 2001 From: Elm1992 Date: Sun, 17 Aug 2025 23:46:27 +0800 Subject: [PATCH 1/4] fix: meta.link invalid issue --- .../effects/layouts/src/basic/menu/use-navigation.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/effects/layouts/src/basic/menu/use-navigation.ts b/packages/effects/layouts/src/basic/menu/use-navigation.ts index 6ba484a4..daa6dc71 100644 --- a/packages/effects/layouts/src/basic/menu/use-navigation.ts +++ b/packages/effects/layouts/src/basic/menu/use-navigation.ts @@ -29,7 +29,8 @@ function useNavigation() { return true; } const route = routeMetaMap.get(path); - return route?.meta?.openInNewWindow ?? false; + // 如果有外链或者设置了在新窗口打开,返回 true + return !!(route?.meta?.link || route?.meta?.openInNewWindow); }; const resolveHref = (path: string): string => { @@ -39,7 +40,13 @@ function useNavigation() { const navigation = async (path: string) => { try { const route = routeMetaMap.get(path); - const { openInNewWindow = false, query = {} } = route?.meta ?? {}; + const { openInNewWindow = false, query = {}, link } = route?.meta ?? {}; + + // 检查是否有外链 + if (link && typeof link === 'string') { + openWindow(link, { target: '_blank' }); + return; + } if (isHttpUrl(path)) { openWindow(path, { target: '_blank' }); From 8ac2db5b7cf6468378afdfc8565d18a08527fcac Mon Sep 17 00:00:00 2001 From: ming4762 Date: Tue, 19 Aug 2025 16:46:14 +0800 Subject: [PATCH 2/4] fix: fix the issue of `VbenForm` `compact` reactive failure (#6654) --- packages/@core/ui-kit/form-ui/src/form-render/form-field.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue b/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue index 67ea58a5..d650b849 100644 --- a/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue +++ b/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue @@ -59,7 +59,7 @@ const values = useFormValues(); const errors = useFieldError(fieldName); const fieldComponentRef = useTemplateRef('fieldComponentRef'); const formApi = formRenderProps.form; -const compact = formRenderProps.compact; +const compact = computed(() => formRenderProps.compact); const isInValid = computed(() => errors.value?.length > 0); const FieldComponent = computed(() => { From 3ad433a50b4428a6ed013c12e878e34cddcf71ba Mon Sep 17 00:00:00 2001 From: Svend Date: Tue, 19 Aug 2025 16:47:45 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=9C=A8=20hash?= =?UTF-8?q?=20=E8=B7=AF=E7=94=B1=E6=A8=A1=E5=BC=8F=E4=B8=8B=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E5=9C=A8=E6=96=B0=E7=AA=97=E5=8F=A3=E6=89=93=E5=BC=80?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=9A=84=E9=97=AE=E9=A2=98=20(#6652)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 此问题是由于 PR #6583 中新增的 `resolveHref` 函数导致的。其在 hash 路由模式下,得到的 URL 会包含 #/ 前缀。在经过 openRouteInNewWindow 的逻辑后就会出现两次 /# 前缀 --- packages/@core/base/shared/src/utils/window.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@core/base/shared/src/utils/window.ts b/packages/@core/base/shared/src/utils/window.ts index 4608f4be..2d8697de 100644 --- a/packages/@core/base/shared/src/utils/window.ts +++ b/packages/@core/base/shared/src/utils/window.ts @@ -30,7 +30,7 @@ function openWindow(url: string, options: OpenWindowOptions = {}): void { function openRouteInNewWindow(path: string) { const { hash, origin } = location; const fullPath = path.startsWith('/') ? path : `/${path}`; - const url = `${origin}${hash ? '/#' : ''}${fullPath}`; + const url = `${origin}${hash && !fullPath.startsWith('/#') ? '/#' : ''}${fullPath}`; openWindow(url, { target: '_blank' }); } From 58e394181042351a03d4897349e893fa1a86d5cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A6=E5=85=83=E5=90=89?= <87116441+qianYuanJ@users.noreply.github.com> Date: Tue, 19 Aug 2025 16:48:10 +0800 Subject: [PATCH 4/4] chore(docs): update the component import of the form adapter description in the document (#6656) --- docs/src/components/common-ui/vben-form.md | 70 ++++++++++++++-------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/docs/src/components/common-ui/vben-form.md b/docs/src/components/common-ui/vben-form.md index 9485af96..0ed02384 100644 --- a/docs/src/components/common-ui/vben-form.md +++ b/docs/src/components/common-ui/vben-form.md @@ -90,30 +90,52 @@ import { h } from 'vue'; import { globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; -import { - AutoComplete, - Button, - Checkbox, - CheckboxGroup, - DatePicker, - Divider, - Input, - InputNumber, - InputPassword, - Mentions, - notification, - Radio, - RadioGroup, - RangePicker, - Rate, - Select, - Space, - Switch, - Textarea, - TimePicker, - TreeSelect, - Upload, -} from 'ant-design-vue'; +const AutoComplete = defineAsyncComponent( + () => import('ant-design-vue/es/auto-complete'), +); +const Button = defineAsyncComponent(() => import('ant-design-vue/es/button')); +const Checkbox = defineAsyncComponent( + () => import('ant-design-vue/es/checkbox'), +); +const CheckboxGroup = defineAsyncComponent(() => + import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup), +); +const DatePicker = defineAsyncComponent( + () => import('ant-design-vue/es/date-picker'), +); +const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider')); +const Input = defineAsyncComponent(() => import('ant-design-vue/es/input')); +const InputNumber = defineAsyncComponent( + () => import('ant-design-vue/es/input-number'), +); +const InputPassword = defineAsyncComponent(() => + import('ant-design-vue/es/input').then((res) => res.InputPassword), +); +const Mentions = defineAsyncComponent( + () => import('ant-design-vue/es/mentions'), +); +const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio')); +const RadioGroup = defineAsyncComponent(() => + import('ant-design-vue/es/radio').then((res) => res.RadioGroup), +); +const RangePicker = defineAsyncComponent(() => + import('ant-design-vue/es/date-picker').then((res) => res.RangePicker), +); +const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate')); +const Select = defineAsyncComponent(() => import('ant-design-vue/es/select')); +const Space = defineAsyncComponent(() => import('ant-design-vue/es/space')); +const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch')); +const Textarea = defineAsyncComponent(() => + import('ant-design-vue/es/input').then((res) => res.Textarea), +); +const TimePicker = defineAsyncComponent( + () => import('ant-design-vue/es/time-picker'), +); +const TreeSelect = defineAsyncComponent( + () => import('ant-design-vue/es/tree-select'), +); +const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload')); + const withDefaultPlaceholder = ( component: T,