Register local Vue.js component dynamically

As of Vue 2.6, this cannot be done. Dynamic registration can only be done globally, using Vue.component.


This is how I ended up importing and registering components dynamically to a component locally:

created() {
  const requireComponent = require.context(
    // The relative path of the components folder
    "PATH/TO/COMPONENTS_FOLDER",
    // Whether or not to look in subfolders
    false,
    // The regular expression used to match base component filenames
    /[A-Z]\w+\.(vue|js)$/
  );

  requireComponent.keys().forEach(fileName => {
    const componentConfig = requireComponent(fileName);
    console.log(componentConfig.default);
    // Gets the file name regardless of folder depth
    const componentName = fileName
      .split("/")
      .pop()
      .split(".")[0];
    // register the component locally
    this.$options.components[componentName] = componentConfig.default;
  });
}

Please notice that the components have to be registered before the component is mounted, the created life-cycle hook can be perfect for that.

See also the docs for Automatic Global Registration of Base Components.


This is how you implement a dynamic component, not how to register a dynamic component. In .vue files you can only register a single component, any others would need to be defined externally.

You should be able to achieve what you're looking to accomplish using the :is attribute. Here's the example from the docs:

var vm = new Vue({
    el: '#example',
    data: {
        currentView: 'home'
    },
    components: {
        home: { /* ... */ },
        posts: { /* ... */ },
        archive: { /* ... */ }
    }
})
<component v-bind:is="currentView">
    <!-- component changes when vm.currentView changes! -->
</component>

or an alternative, where you bind directly to the component object (instead of using some data as a pointer):

var Home = {
    template: '<p>Welcome home!</p>'
}
var vm = new Vue({
    el: '#example',
    data: {
        currentView: Home
    }
})