Vue3 TypeScript Class Component props定义报非构造函数错误
问题原因
这个报错和props写法没有任何关系,错误栈定位到prop配置行是sourcemap映射偏移造成的误导,核心问题出在两个地方:
- 递归组件自注册缺失:
SubMenu组件在自身模板里递归调用了<SubMenu>标签,但你只在父级Menu组件的components选项里注册了SubMenu,SubMenu自身的@Options配置里没有注册自身,组件解析到内部递归的SubMenu标签时找不到对应的组件构造函数。 - webpack ES模块循环引用初始化时序问题:递归组件自引用时,模块在自身初始化阶段导入自己,webpack返回的导出值在初始执行阶段是还没完成初始化的空值,直接抛出
default is not a constructor错误。
之前改PropType、改prop默认值的操作全是在错误方向排查,自然解决不了问题。
修复方案
任选一种方案即可解决问题:
方案1:组件内自注册(最适配当前代码结构)
你已经在SubMenu的@Options里配置了name: 'SubMenu',只需要在components选项里注册自身即可:
@Options({ name: 'SubMenu', components: { SubMenu }, // 新增这行,注册自身组件 props: { items: Array as PropType<MenuItem[]>, root: { type: Boolean, default: false } } })
如果加完还是报导入值为空的错,就把注册改为异步延迟导入,避开初始化时序问题:
components: { SubMenu: () => import('@/components/SubMenu.vue') }
方案2:全局注册组件
如果SubMenu是项目通用的菜单组件,直接在项目入口文件全局注册即可,不需要在每个用到的组件(包括自身)里单独注册:
// 项目入口main.ts中 import SubMenu from '@/components/SubMenu.vue' app.component('SubMenu', SubMenu)
额外模板bug修复
当前模板里的分隔符渲染逻辑有问题:不管菜单项是不是分隔符类型,都会渲染一个分隔符li标签。需要把判断条件挪到分隔符标签上,避免多余的分割线:
<!-- 替换原来无判断条件的<li class="separator" /> --> <li v-if="item.separator" class="separator" />
内容的提问来源于stack exchange,提问作者driima
相关产品推荐
相关产品推荐

