Skip to content

[HeadMenu] 封装组件插槽返回单个 VNode 时抛出 nodes is not iterable #6857

Description

@zhangpaopao0609

tdesign-vue-next 版本

当前 develop(复现基线:9e47c828a

重现步骤

在 render/JSX 中通过封装组件组织 HeadMenu 菜单项,并让尚未挂载的封装组件默认插槽直接返回一个 VNode:

const MenuContent = defineComponent({
  setup(_, { slots }) {
    return () => <div>{slots.default?.()}</div>;
  },
});

mount(HeadMenu, {
  props: { expandType: 'popup' },
  slots: {
    default: () => h(MenuContent, null, {
      default: () => <MenuItem value="one">One</MenuItem>,
    }),
  },
});

期望结果

HeadMenu 能兼容插槽返回单个 VNode 或 VNode 数组,并正常计算菜单项及溢出折叠。

实际结果

挂载时直接抛出:

TypeError: nodes is not iterable

原因定位

packages/components/menu/head-menu.tsxflattenSlotNodes 在处理封装组件时直接执行:

flattenSlotNodes((node.children as any).default())

这里假设 slot 函数始终返回 VNode[]。但 HeadMenu 正在检查尚未挂载、尚未被 Vue 规范化的 VNode,合法的 render slot 可以直接返回单个 VNode,随后 for (const node of nodes) 就会抛错。

建议递归前统一将结果规范化为数组。

补充说明

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions