admin管理员组

文章数量:1323549

Currently I am loading all of my Vue ponents with require.context, this searches my ponents directory with a regex for .vue files. This works fine but I would like to load async ponents as well with dynamic imports.

Currently when I use require.context all files get loaded so even If I want to use a dynamic import my file is already loaded and nothing happens.

I need a way to exclude certain files from my require.context call. I cannot dynamically create a regex because this does not work with require.context.

// How I currently load my Vue ponents.

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

ponents.keys().forEach((filePath) => {
    const ponent = ponents(filePath);
    const ponentName = path.basename(filePath, '.vue');

    // Dynamically register the ponent.
    Vueponent(ponentName, ponent);
});

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

It seems the only way to do this is either manually declare all my ponents, which is a big hassle.

Or to create a static regex that skips files that have Async in their name. Which forces me to adopt a certain naming convention for ponents that are async. Also not ideal.

Would there be a better way to go about doing this?

Currently I am loading all of my Vue ponents with require.context, this searches my ponents directory with a regex for .vue files. This works fine but I would like to load async ponents as well with dynamic imports.

Currently when I use require.context all files get loaded so even If I want to use a dynamic import my file is already loaded and nothing happens.

I need a way to exclude certain files from my require.context call. I cannot dynamically create a regex because this does not work with require.context.

// How I currently load my Vue ponents.

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

ponents.keys().forEach((filePath) => {
    const ponent = ponents(filePath);
    const ponentName = path.basename(filePath, '.vue');

    // Dynamically register the ponent.
    Vue.ponent(ponentName, ponent);
});

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

It seems the only way to do this is either manually declare all my ponents, which is a big hassle.

Or to create a static regex that skips files that have Async in their name. Which forces me to adopt a certain naming convention for ponents that are async. Also not ideal.

Would there be a better way to go about doing this?

Share Improve this question asked Apr 25, 2018 at 13:09 Stephan-vStephan-v 20.4k32 gold badges121 silver badges210 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5
const requireContext = require.context('./ponents', false, /.*\.vue$/)

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

Works with Vue 2.7 and Vue 3.

The lazy mode forces requireContext to return a 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-ponent-name$/)
  const promise = requireContext(file)
  dynamicComponents[name] = defineAsyncComponent(() => promise)
  return dynamicComponents
}, {})

You can also use defineAsyncComponent({ loader: () => promise }) if you want to use the extra options of defineAsyncComponent.

本文标签: javascriptHow to dynamically load a Vue component after using requirecontextStack Overflow