如何在使用require.context后动态加载Vue组件?

8

目前我使用require.context加载所有的Vue组件,它会在我的components目录中查找以.vue为后缀的文件。这个方法可以正常工作,但是我也想用动态导入来加载异步组件。

但是使用require.context时,所有的文件都会被加载,即使我想要使用动态导入,文件已经被加载了,所以什么都不会发生。

我需要一种方式从require.context调用中排除某些文件。因为这种方式无法与require.context动态创建正则表达式。

// How I currently load my Vue components.

const components = require.context('@/components', true, /[A-Z]\w+\.vue$/);

components.keys().forEach((filePath) => {
    const component = components(filePath);
    const componentName = path.basename(filePath, '.vue');

    // Dynamically register the component.
    Vue.component(componentName, component);
});

// My component that I would like to load dynamically.
Vue.component('search-dropdown', () => import('./search/SearchDropdown'));

看起来唯一的方法是手动声明我所有的组件,这很麻烦。

或者创建一个静态正则表达式,跳过文件名中带有Async的文件。这强制我采用一定的异步组件命名约定,也不是理想的选择。

是否有更好的方法来处理这个问题?

2个回答

5
const requireContext = require.context('./components', false, /.*\.vue$/)

const dynamicComponents = requireContext.keys()
    .map(file =>
        [file.replace(/(^.\/)|(\.vue$)/g, ''), requireContext(file)]
    )
    .reduce((components, [name, component]) => {
        components[name] = component.default || component
        return components
    }, {})

1

适用于Vue 2.7和Vue 3。

lazy模式强制requireContext返回一个promise

const { defineAsyncComponent } = require('vue')

const requireContext = require.context('./yourfolder', true, /^your-regex$/, 'lazy')
module.exports = requireContext.keys().reduce((dynamicComponents, file) => {
  const [, name] = file.match(/^regex-to-match-component-name$/)
  const promise = requireContext(file)
  dynamicComponents[name] = defineAsyncComponent(() => promise)
  return dynamicComponents
}, {})

如果您想使用 defineAsyncComponent({ loader: () => promise }) 的附加选项,也可以使用它。

有关 defineAsyncComponent 的加载和错误状态的额外选项,请参阅相关文档。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接