You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用TypeScript和Vite动态导出Vue3组件?

解决Vite+TypeScript动态导出Vue组件的问题

问题原因

你当前的代码用export default导出了一个包含所有组件的对象,但import { MyButton }是在查找具名导出,而非默认导出对象里的属性,因此会抛出导出不存在的错误。

解决方案1:实现动态具名导出(支持解构导入)

通过动态挂载组件到模块的exports对象上,实现和静态导出一致的效果:

// my-components/index.ts
const modules = import.meta.glob('./src/*.vue', { eager: true })

Object.entries(modules).forEach(([path, module]) => {
  // 从文件路径提取组件名(比如 "./src/MyButton.vue" → "MyButton")
  const componentName = path.match(/\/([^/]+)\.vue$/)?.[1] || ''
  
  // 若组件内通过defineOptions声明了name,也可优先用__name(需Vue 3.3+)
  // const componentName = (module as { default: { __name: string } }).default.__name

  if (componentName) {
    (module.exports as any)[componentName] = (module as { default: any }).default
  }
})

// 可选:添加TypeScript类型提示
export type ComponentExports = {
  [K in keyof typeof modules as K extends `./src/${infer Name}.vue` ? Name : never]: 
  typeof modules[K]['default']
}

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

使用方式和你预期一致:

<script setup lang="ts">
import { MyButton, MyInput } from '@/components/my-components'
</script>

解决方案2:默认导出对象(调整导入逻辑)

如果不想修改导出逻辑,可保持默认导出,调整导入方式即可:

// my-components/index.ts
const modules: Record<string, any> = import.meta.glob('./src/*.vue', { eager: true })

const exportData: Record<string, any> = {};
Object.keys(modules).forEach(component => {
  // 优先用组件声明的__name,否则从路径提取
  const name = modules[component].default.__name || 
    component.replace(/^\.\/src\/(.*)\.vue$/, '$1')
  exportData[name] = modules[component].default
})

export default exportData

导入时解构默认导出的对象:

<script setup lang="ts">
import Components from '@/components/my-components'
const { MyButton, MyInput } = Components
</script>

注意事项

  • 若使用组件的__name属性,在<script setup>中需通过defineOptions显式声明组件名(Vue 3.3+支持):
    <script setup lang="ts">
    defineOptions({
      name: 'MyButton'
    })
    </script>
    
  • import.meta.glob的eager: true必须添加,否则组件会被懒加载,无法立即导出。

内容的提问来源于stack exchange,提问作者Gerard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 13:36:02