silverxjohn's avatar

Vue component not registered

I can't seem to make Vue components work on my Laravel 5.4 installation.

I register my components in resources/assets/js/app.js

Vue.component(
    'box',
    require('./components/Box.vue')
);

I also register Laravel Passport's vue components in the same file:resources/assets/js/app.js

And in resources/assets/js/components/Box.vue

<template>
    <div class="box box-solid box-primary">
        <div class="box-header">
            <h3 class="box-title">{{ title }}</h3>
        </div>
        <div class="box-body">
            <slot></slot>
        </div>
    </div>
</template>

<script>
    export default {
        props: ['title'],
        data() {
            return {
                title: 'Box Title'
            }
        }
    }
</script>

Then I run npm run dev to compile my code to public/js/app.js which is then 'registered' in a master layout's <head>.

And when I try to use it in a view:

<div id="app">
    <box title="This is my Box">
        <h1>I'm inside this box</h1>
    </box>
</div>
const vm = new Vue({
    el: "#app"
});

I get the following message: 'Did you register the component correctly?'

It all works when I register the component in the same .js file where I put the const vm = new Vue({ /*...*/ }).

I also check the output public/js/app.js and I see that my component is being 'registered'

Do I need to do something else to make it work or am I doing all this in a wrong way?

0 likes
16 replies
topvillas's avatar

You're using a single file component, you don't need to register it as a component.

Just import the component and add it to the VM's components property ...

var box = require('./path/to/component.vue);

var vm = new Vue({
    components: {
        box 
    }
})

or

var vm = new Vue({
    components: {
        box: require('./path/to/component.vue)
    }
})
silverxjohn's avatar

@topvillas I'm still getting an error

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

What I want is to register the components globally so that I could use it in any Vue instances.

topvillas's avatar

In that case, go with your original code but don't use a single file component.

Just make the component a standard js file and use the template property.

Hint: If you want to keep the template separate rather than putting a horrible string of HTML in the script. Create an HTML file and import it into the component in the template property. But, you'll have to use a Webpack loader ...

https://github.com/webpack-contrib/html-loader

MaverickChan's avatar

@silverxjohn

the Vue warning is very friendly , it tells you the best way.

so add a

name : 'box',

inside export default

everything should be fine

silverxjohn's avatar

@MaverickChan Thanks for your response. I add the name: 'box', as you suggested so my Box.vue looks like

<template>
    <div class="box box-solid box-primary">
        <div class="box-header">
            <h3 class="box-title">{{ title }}</h3>
        </div>
        <div class="box-body">
            <slot></slot>
        </div>
    </div>
</template>

<script>
    export default {
        name: 'box',
        props: ['title'],
        data() {
            return {
                title: 'Box'
            }
        }
    }
</script>

But it still doesn't work. I also follow the documentation on Laravel Passport on how it registers the custom components like <passport-clients></passport-clients> and it's not working either. Any more suggestions?

If this would help in anyway. In the compiled app.js I see this:

Vue.component('box', __webpack_require__(45));

/*  . . .  */

__webpack_exports__["default"] = ({
    name: 'box',
    props: ['title'],
    data: function data() {
        return {
            title: 'Box'
        };
    }
});
MaverickChan's avatar

@silverxjohn

i notice that in your file

var vm = new Vue({
    components: {
        box: require('./path/to/component.vue)
    }
})

it should be

var vm = new Vue({
    components: {
        'box': require('./path/to/component.vue)
    }
})

need to quote box.

1 like
mdecooman's avatar

Hi @silverxjohn

In your app.js, you already declare a vue instance with the element #app. You either do it here or in your view, not both.

Also your component is declared in your app.js

Vue.component(
    'box',
    require('./components/Box.vue')
);

So no need to declare it again in your views. That is probably where the confusion starts.

silverxjohn's avatar

@mdecooman Thank you for the response. I'm sorry I shouldn't have committed that on master. Even if I remove the const app = ... from resources/assets/js/app.js, it still doesn't work.

I tried to define the template from my views so I know that the component is working. If I remove the definition of box component in my view file, it will show an error in the console (see above replies) and the box component wouldn't render at all even though the component was registered in resources/assets/js/app.js globally.

I do tried to clear my browsers cache and even use different browser with no luck. I also tried deleting npm modules and re-install them.

dawidryba's avatar

Hello, Try this: Child component:

<template>
 <div>some content</div>
</template>

<script>
export default {
  name: 'name-component',
  data() {
    return {
      date: 'test',
    }
  }
}
</script>

And in parent try this:

<template>
some content
 <vue-component></vue-component>
some content
</template>
<script>
    import name-component from './component-file.vue';

    export default {
      components: {
        'vue-component': name-component,
      }
    }
</script>
mdecooman's avatar

@silverxjohn

Just make sure you do not use any script in you views that it will not understood because it would need to be interpreted first by a webpack or else.

mdecooman's avatar

It is ok. Seems you solved more than one issue here since the error message would have been different if only the csrf token was missing.

That is part of the learning curve so does answering questions and helping. Glad you made it.

1 like
sargilla's avatar

When register your component add .default after of require file, i don't know why but it works! Vue.component( 'box', require('./components/Box.vue').default );

1 like
24Makos's avatar

Ran into same issue, tried all the other suggestions but non worked until i added .default after require. please can someone explain that to me?

dwoodard's avatar

This was my issue

component: {
      "box": Box
    },

VS

components: { //<-- notice the s 
      "box": Box
    },

Please or to participate in this conversation.