This commit is contained in:
dap
2025-05-04 17:23:32 +08:00
60 changed files with 498 additions and 210 deletions

View File

@@ -74,7 +74,7 @@ async function generateAccessible(
}
// 生成菜单
const accessibleMenus = await generateMenus(accessibleRoutes, options.router);
const accessibleMenus = generateMenus(accessibleRoutes, options.router);
return { accessibleMenus, accessibleRoutes };
}

View File

@@ -165,13 +165,18 @@ const searchInputProps = computed(() => {
};
});
function updateCurrentSelect(v: string) {
currentSelect.value = v;
}
defineExpose({ toggleOpenState, open, close });
</script>
<template>
<VbenPopover
v-model:open="visible"
:content-props="{ align: 'end', alignOffset: -11, sideOffset: 8 }"
content-class="p-0 pt-3"
content-class="p-0 pt-3 w-full"
trigger-class="w-full"
>
<template #trigger>
<template v-if="props.type === 'input'">
@@ -183,6 +188,7 @@ defineExpose({ toggleOpenState, open, close });
role="combobox"
:aria-label="$t('ui.iconPicker.placeholder')"
aria-expanded="visible"
:[`onUpdate:${modelValueProp}`]="updateCurrentSelect"
v-bind="$attrs"
>
<template #[iconSlot]>

View File

@@ -35,6 +35,16 @@ const getZIndex = computed(() => {
return props.zIndex || calcZIndex();
});
/**
* 排除ant-message和loading:9999的z-index
*/
const zIndexExcludeClass = ['ant-message', 'loading'];
function isZIndexExcludeClass(element: Element) {
return zIndexExcludeClass.some((className) =>
element.classList.contains(className),
);
}
/**
* 获取最大的zIndex值
*/
@@ -44,7 +54,11 @@ function calcZIndex() {
[...elements].forEach((element) => {
const style = window.getComputedStyle(element);
const zIndex = style.getPropertyValue('z-index');
if (zIndex && !Number.isNaN(Number.parseInt(zIndex))) {
if (
zIndex &&
!Number.isNaN(Number.parseInt(zIndex)) &&
!isZIndexExcludeClass(element)
) {
maxZ = Math.max(maxZ, Number.parseInt(zIndex));
}
});

View File

@@ -37,6 +37,7 @@ function handleMenuOpen(key: string, path: string[]) {
:menus="menus"
:mode="mode"
:rounded="rounded"
scroll-to-active
:theme="theme"
@open="handleMenuOpen"
@select="handleMenuSelect"

View File

@@ -6,39 +6,55 @@ import { isHttpUrl, openRouteInNewWindow, openWindow } from '@vben/utils';
function useNavigation() {
const router = useRouter();
const routes = router.getRoutes();
const routeMetaMap = new Map<string, RouteRecordNormalized>();
routes.forEach((route) => {
routeMetaMap.set(route.path, route);
// 初始化路由映射
const initRouteMetaMap = () => {
const routes = router.getRoutes();
routes.forEach((route) => {
routeMetaMap.set(route.path, route);
});
};
initRouteMetaMap();
// 监听路由变化
router.afterEach(() => {
initRouteMetaMap();
});
const navigation = async (path: string) => {
const route = routeMetaMap.get(path);
const { openInNewWindow = false, query = {} } = route?.meta ?? {};
// 检查是否应该在新窗口打开
const shouldOpenInNewWindow = (path: string): boolean => {
if (isHttpUrl(path)) {
openWindow(path, { target: '_blank' });
} else if (openInNewWindow) {
openRouteInNewWindow(path);
} else {
await router.push({
path,
query,
});
return true;
}
const route = routeMetaMap.get(path);
return route?.meta?.openInNewWindow ?? false;
};
const navigation = async (path: string) => {
try {
const route = routeMetaMap.get(path);
const { openInNewWindow = false, query = {} } = route?.meta ?? {};
if (isHttpUrl(path)) {
openWindow(path, { target: '_blank' });
} else if (openInNewWindow) {
openRouteInNewWindow(path);
} else {
await router.push({
path,
query,
});
}
} catch (error) {
console.error('Navigation failed:', error);
throw error;
}
};
const willOpenedByWindow = (path: string) => {
const route = routeMetaMap.get(path);
const { openInNewWindow = false } = route?.meta ?? {};
if (isHttpUrl(path)) {
return true;
} else if (openInNewWindow) {
return true;
} else {
return false;
}
return shouldOpenInNewWindow(path);
};
return { navigation, willOpenedByWindow };

View File

@@ -11,7 +11,8 @@ defineOptions({
name: 'LanguageToggle',
});
async function handleUpdate(value: string) {
async function handleUpdate(value: string | undefined) {
if (!value) return;
const locale = value as SupportedLanguagesType;
updatePreferences({
app: {

View File

@@ -36,7 +36,8 @@ const menus = computed((): VbenDropdownMenuItem[] => [
const { authPanelCenter, authPanelLeft, authPanelRight } = usePreferences();
function handleUpdate(value: string) {
function handleUpdate(value: string | undefined) {
if (!value) return;
updatePreferences({
app: {
authPageLayout: value as AuthPageLayoutType,

View File

@@ -79,14 +79,14 @@ const handleCheckboxChange = () => {
</SwitchItem>
<CheckboxItem
:items="[
{ label: '收缩按钮', value: 'collapsed' },
{ label: '固定按钮', value: 'fixed' },
{ label: $t('preferences.sidebar.buttonCollapsed'), value: 'collapsed' },
{ label: $t('preferences.sidebar.buttonFixed'), value: 'fixed' },
]"
multiple
v-model="sidebarButtons"
:on-btn-click="handleCheckboxChange"
>
按钮配置
{{ $t('preferences.sidebar.buttons') }}
</CheckboxItem>
<NumberFieldItem
v-model="sidebarWidth"

View File

@@ -24,7 +24,7 @@ withDefaults(defineProps<{ shouldOnHover?: boolean }>(), {
shouldOnHover: false,
});
function handleChange(isDark: boolean) {
function handleChange(isDark: boolean | undefined) {
updatePreferences({
theme: { mode: isDark ? 'dark' : 'light' },
});