修复左边栏折叠后图标无法显示的问题
This commit is contained in:
parent
4f27721cd1
commit
c2af4a2623
@ -11,7 +11,7 @@
|
|||||||
@collapse="handleCollapse"
|
@collapse="handleCollapse"
|
||||||
@expand="handleExpand"
|
@expand="handleExpand"
|
||||||
>
|
>
|
||||||
<div class="flex h-full flex-col">
|
<div style="display: block; height: 100%;">
|
||||||
<!-- 用户信息区域 -->
|
<!-- 用户信息区域 -->
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<n-dropdown
|
<n-dropdown
|
||||||
@ -54,10 +54,12 @@
|
|||||||
<n-menu
|
<n-menu
|
||||||
:collapsed="collapsed"
|
:collapsed="collapsed"
|
||||||
:collapsed-width="64"
|
:collapsed-width="64"
|
||||||
|
:collapsed-icon-size="24"
|
||||||
:options="convertToMenuOptions(navigation)"
|
:options="convertToMenuOptions(navigation)"
|
||||||
:value="activeKey"
|
:value="activeKey"
|
||||||
:router="false"
|
:router="false"
|
||||||
@update:value="handleMenuSelect"
|
@update:value="handleMenuSelect"
|
||||||
|
class="app-sidebar-menu"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</NavigationItems>
|
</NavigationItems>
|
||||||
@ -72,7 +74,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { defineAsyncComponent, computed, ref, h, getCurrentInstance } from 'vue';
|
import { defineAsyncComponent, computed, ref, h, getCurrentInstance } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
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 NavigationItems from './NavigationItems.vue';
|
||||||
import JLogo from '@/components/icons/JLogo.vue';
|
import JLogo from '@/components/icons/JLogo.vue';
|
||||||
|
|
||||||
@ -83,6 +85,7 @@ export default {
|
|||||||
NMenu,
|
NMenu,
|
||||||
NDropdown,
|
NDropdown,
|
||||||
NTooltip,
|
NTooltip,
|
||||||
|
NIcon,
|
||||||
NavigationItems,
|
NavigationItems,
|
||||||
JLogo,
|
JLogo,
|
||||||
SwitchTeamDialog2: defineAsyncComponent(() =>
|
SwitchTeamDialog2: defineAsyncComponent(() =>
|
||||||
@ -166,18 +169,64 @@ export default {
|
|||||||
|
|
||||||
// 转换导航项为菜单选项
|
// 转换导航项为菜单选项
|
||||||
const convertToMenuOptions = (items) => {
|
const convertToMenuOptions = (items) => {
|
||||||
if (!items || !Array.isArray(items)) return [];
|
if (!items || !Array.isArray(items)) {
|
||||||
|
console.warn('[AppSidebar] convertToMenuOptions: invalid items', items);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
return items
|
return items
|
||||||
.filter((item) => item.condition !== false)
|
.filter((item) => item.condition !== false)
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
|
console.log(`[AppSidebar] Processing "${item.name}":`, {
|
||||||
|
hasIcon: !!item.icon,
|
||||||
|
iconType: typeof item.icon,
|
||||||
|
collapsed: collapsed.value
|
||||||
|
});
|
||||||
// 处理图标:item.icon 是一个函数,返回 h() 创建的组件
|
// 处理图标:item.icon 是一个函数,返回 h() 创建的组件
|
||||||
// Naive UI 的 n-menu 需要 icon 是一个渲染函数
|
// Naive UI 的 n-menu 需要 icon 是一个渲染函数
|
||||||
let iconComponent = undefined;
|
let iconComponent = undefined;
|
||||||
if (item.icon) {
|
if (item.icon) {
|
||||||
// item.icon 本身就是一个函数,直接使用
|
iconComponent = () => {
|
||||||
// 但需要确保它返回一个有效的 VNode
|
try {
|
||||||
iconComponent = item.icon;
|
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')
|
// 处理路由:NavigationItems 中的 route 已经是相对于 /dashboard/ 的路径(如 '/sites')
|
||||||
@ -249,11 +298,13 @@ export default {
|
|||||||
|
|
||||||
// 处理折叠
|
// 处理折叠
|
||||||
const handleCollapse = () => {
|
const handleCollapse = () => {
|
||||||
|
console.log('[AppSidebar] handleCollapse called');
|
||||||
emit('update:collapsed', true);
|
emit('update:collapsed', true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理展开
|
// 处理展开
|
||||||
const handleExpand = () => {
|
const handleExpand = () => {
|
||||||
|
console.log('[AppSidebar] handleExpand called');
|
||||||
emit('update:collapsed', false);
|
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>
|
||||||
Loading…
x
Reference in New Issue
Block a user