vue3.2全局导入组件-路径问题?

关于vue3全局自动导入组件的问题,浏览器打开组件总是报错文件路径不对

环境为vue3.2,webpack的配置

main.js 导入了全局导入的文件

import mLibs from './lib/index'
app.use(mLibs)

./lib/index.js的内容,组件.vue都在lib文件夹下,都有文件夹包裹.此处将component常量写死了路径,效果是正常的(未注释行代码的上一行).图片放在最底部.但如果用路径拼接,就会报错'Cannot find module ',报错图片也放置在最后一行.

import { defineAsyncComponent } from 'vue'
export default {
      install(app) {
        // 获取当前路径任意文件夹下的 index.vue 文件
        const requireComponent = require.context('@/lib/', true, /\.vue$/)
        // 遍历获取到的组件模块
        requireComponent.keys().forEach(fileName => {
          const componentName = fileName.split('/').pop().replace('.vue', '') // 获取组件名
          const componentPath = fileName.replace('.', '../lib')
          const component = defineAsyncComponent(() => import('../lib/platform/roleAddEdit.vue'))
          // const component = defineAsyncComponent(() => import(componentPath))
          console.log(componentName, component, componentPath)
          app.component(componentName, component)
    })
      }
}

使用场景是在element-plus中

<el-dialog
  v-model='dialogShow'
  :title='dialogTitle'
  destroy-on-close
  center
  draggable
  :close-on-click-modal='false'
  width='450px'
>
      <component @cancel='cancel' :is='componentName' :dialogTitle='dialogTitle' :form='form'></component>
    </el-dialog>
const addDialogShow = () => {
  dialogShow.value = true
  componentName.value = 'roleAddEdit'
  dialogTitle.value = '新增角色'
  form.value = {}
}

image.png
image.png

还望大佬能够加以指正,非常感谢大佬

阅读 1.7k
avatarAI BotBETA

这个问题似乎是由于 webpack 的动态导入和 vue 的异步组件结合使用时路径问题导致的。

在你的代码中,你使用了 webpack 的 require.context 来动态加载组件。这种方式在路径拼接时,如果路径写错或者存在一点小错误,webpack 是无法正确地找到模块的,因此会报出 'Cannot find module' 的错误。

你的代码中,动态加载组件的部分如下:

const component = defineAsyncComponent(() => import('../lib/platform/roleAddEdit.vue'))

在这段代码中,../lib/platform/roleAddEdit.vue 是动态拼接的路径。如果在拼接过程中,路径写错或者存在一点小错误,就会导致无法找到正确的模块,从而报出错误。

一个可能的解决方案是,使用固定的路径来加载组件,而不是动态拼接。你可以在 require.context 中直接指定要加载的路径和文件后缀。例如:

const requireComponent = require.context('@/lib/', true, /\.vue$/)

这段代码会告诉 webpack 在 @/lib/ 目录下查找所有 .vue 文件。这样,不管你的项目结构如何变化,只要文件在正确的位置,就可以被正确地加载。

如果你要使用动态路径,你需要保证你的路径是正确的。你可以使用 webpack 的 resolve.alias 功能来设置路径别名,这样就可以避免手动拼接路径的错误。例如:

const path = require('path');

module.exports = {
  //...
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './lib'),
    },
  },
};

这样,你就可以使用 @/index.js 来代替 ../lib/index.js,使用 @/platform/roleAddEdit.vue 来代替 ../lib/platform/roleAddEdit.vue。这样就可以避免因为路径错误导致的 'Cannot find module' 错误。

2 个回答
import { defineAsyncComponent } from 'vue'
export default {
  install(app) {
    // 获取当前路径任意文件夹下的 index.vue 文件
    const requireComponent = require.context('@/lib/', true, /\.vue$/)
    requireComponent.keys().forEach((fileName) => {
      const componentName = fileName.split('/').pop().replace('.vue', '') // 获取组件名
      const componentPath = requireComponent(fileName).default
      const component = defineAsyncComponent(() => {
        return new Promise(resolve => {
          resolve(componentPath)
        })
      })
      app.component(componentName, component)
    })
  }
}

经测试将lib/index.js 改为如下代码即可

The import() must contain at least some information about where the module is located. Bundling can be limited to a specific directory or set of files so that when you are using a dynamic expression - every module that could potentially be requested on an import() call is included. For example, import(./locale/${language}.json) will cause every .json file in the ./locale directory to be bundled into the new chunk. At run time, when the variable language has been computed, any file like english.json or german.json will be available for consumption.

https://webpack.js.org/api/module-methods/#dynamic-expression...

import不能直接用变量,起码要限定在某个文件夹下, 尝试这样:

const component = defineAsyncComponent(() => import('@/lib/' + componentPath))
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题