Search code examples
vuejs2webpack-4

Automatic global register vue single file components from folder


I collect all my simple global components in ./components/basic folder and I want to auto register it globally.

Here is the code:

import Vue from "vue";
import upperFirst from 'lodash/upperFirst';
import camelCase from 'lodash/camelCase';


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

requireComponent.keys().forEach(fileName => {
    const componentConfig = requireComponent(fileName)
    const componentName = upperFirst(camelCase(fileName.split('/').pop().replace(/\.\w+$/, '')));
    Vue.component(componentName, componentConfig.default || componentConfig);
  });

new Vue({
    el: "#app"
});

index.html fragment:

<body>
    <div id="app">  
        <MyBasic></MyBasic>
    </div>
    <script src="./dist/main.js"></script>
</body>

And finally a component MyBasic.vue:

<template>
    <h1>My basic component</h1>
</template>

<script>
    export default {
        name: 'MyBasic',
        data(){   
            return{
                header: "Hi!"
            }
        }
    }
</script>

<style></style>

Evething seems right, but in fact it throws warning to console and my component doesn't works:

[Vue warn]: Unknown custom element: <mybasic> - did you register the component correctly? For recursive components, make sure to provide the "name" option. (found in Root)

What is going wrong with the register script?


Solution

  • The problem is that you're using PascalCase directly in the DOM:

    https://v2.vuejs.org/v2/guide/components-registration.html#Name-Casing

    Note, however, that only kebab-case names are valid directly in the DOM (i.e. non-string templates).

    The browser will convert <MyBasic> to <mybasic>, as shown in the error message. You need to use <my-basic> instead within index.html.

    See also https://v2.vuejs.org/v2/style-guide/#Component-name-casing-in-templates-strongly-recommended