dev #3

Merged
jingrow merged 96 commits from dev into main 2026-01-13 22:47:33 +08:00
Showing only changes of commit c2af4a2623 - Show all commits

View File

@ -11,7 +11,7 @@
@collapse="handleCollapse"
@expand="handleExpand"
>
<div class="flex h-full flex-col">
<div style="display: block; height: 100%;">
<!-- 用户信息区域 -->
<div class="p-2">
<n-dropdown
@ -54,10 +54,12 @@
<n-menu
:collapsed="collapsed"
:collapsed-width="64"
:collapsed-icon-size="24"
:options="convertToMenuOptions(navigation)"
:value="activeKey"
:router="false"
@update:value="handleMenuSelect"
class="app-sidebar-menu"
/>
</template>
</NavigationItems>
@ -72,7 +74,7 @@
<script>
import { defineAsyncComponent, computed, ref, h, getCurrentInstance } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { NLayoutSider, NMenu, NDropdown, NTooltip } from 'naive-ui';
import { NLayoutSider, NMenu, NDropdown, NTooltip, NIcon } from 'naive-ui';
import NavigationItems from './NavigationItems.vue';
import JLogo from '@/components/icons/JLogo.vue';
@ -83,6 +85,7 @@ export default {
NMenu,
NDropdown,
NTooltip,
NIcon,
NavigationItems,
JLogo,
SwitchTeamDialog2: defineAsyncComponent(() =>
@ -166,18 +169,64 @@ export default {
//
const convertToMenuOptions = (items) => {
if (!items || !Array.isArray(items)) return [];
if (!items || !Array.isArray(items)) {
console.warn('[AppSidebar] convertToMenuOptions: invalid items', items);
return [];
}
return items
.filter((item) => item.condition !== false)
.map((item) => {
console.log(`[AppSidebar] Processing "${item.name}":`, {
hasIcon: !!item.icon,
iconType: typeof item.icon,
collapsed: collapsed.value
});
// item.icon h()
// Naive UI n-menu icon
let iconComponent = undefined;
if (item.icon) {
// item.icon 使
// VNode
iconComponent = item.icon;
iconComponent = () => {
try {
const iconVNode = item.icon();
// VNode
console.log(`[AppSidebar] Icon render for "${item.name}":`, {
hasVNode: !!iconVNode,
vnodeType: iconVNode?.type,
vnodeTypeName: iconVNode?.type?.name || iconVNode?.type?.__name || iconVNode?.type,
vnodeProps: iconVNode?.props,
vnodeChildren: iconVNode?.children,
shapeFlag: iconVNode?.shapeFlag,
collapsed: collapsed.value
});
// VNode props size
if (iconVNode && !iconVNode.props) {
iconVNode.props = { width: 16, height: 16 };
} else if (iconVNode && iconVNode.props) {
// size
if (!iconVNode.props.width && !iconVNode.props.size) {
iconVNode.props.width = 16;
}
if (!iconVNode.props.height && !iconVNode.props.size) {
iconVNode.props.height = 16;
}
}
// NIcon
const wrapped = h(NIcon, null, { default: () => iconVNode });
console.log(`[AppSidebar] Wrapped icon for "${item.name}":`, {
hasWrapped: !!wrapped,
wrappedType: wrapped?.type,
wrappedChildren: wrapped?.children,
wrappedProps: wrapped?.props
});
return wrapped;
} catch (e) {
console.error(`[AppSidebar] Icon error for "${item.name}":`, e);
return null;
}
};
}
// NavigationItems route /dashboard/ '/sites'
@ -249,11 +298,13 @@ export default {
//
const handleCollapse = () => {
console.log('[AppSidebar] handleCollapse called');
emit('update:collapsed', true);
};
//
const handleExpand = () => {
console.log('[AppSidebar] handleExpand called');
emit('update:collapsed', false);
};
@ -280,4 +331,45 @@ export default {
};
},
};
</script>
</script>
<style scoped>
/* 全局覆盖,确保优先级最高 */
/* 确保菜单图标在折叠状态下正确显示 */
/* 注意:不要覆盖 Naive UI 的默认 display 样式,只调整必要的属性 */
:deep(.app-sidebar-menu.n-menu--collapsed .n-menu-item-content) {
justify-content: center;
}
/* 确保图标 SVG 可见 */
:deep(.app-sidebar-menu .n-icon svg) {
width: 100%;
height: 100%;
display: block;
}
/* 修复 n-layout-sider 的 flex 布局导致图标不显示的问题 */
/* 根源Naive UI 的 .n-layout-sider 默认是 display: flex这会导致内部图标无法正确渲染 */
/* 解决方案:直接覆盖 .n-layout-sider 的 display 属性,使用更高优先级的选择器 */
</style>
<style>
/* 全局样式,不使用 scoped确保能覆盖 Naive UI 的默认样式 */
/* 修复:覆盖 .n-layout-sider 的 display: flex这是导致图标不显示的根本原因 */
.n-layout-sider {
display: block !important;
}
.n-layout-sider .n-layout-sider-scroll-container {
display: block !important;
}
/* 确保所有内部容器都是 block避免 flex 布局影响图标 */
.n-layout-sider > * {
display: block !important;
}
</style>
<style scoped>
</style>