6

I'm learning to use Vue.js with Laravel from this series the narrator doesn't get any error but I've encountered the following error while I click to change the route.

[Vue warn]: Failed to mount component: template or render function not defined.

Below code is from my app.js:

require('./bootstrap');

window.Vue = require('vue');

import VueRouter from 'vue-router'
Vue.use(VueRouter)

let routes = [{
    path: '/dashboard',
    component: require('./components/Dashboard.vue')
  },
  {
    path: '/profile',
    component: require('./components/Profile.vue')
  }
]

const router = new VueRouter({
  routes
})

Vue.component('example-component', require('./components/ExampleComponent.vue'));

const app = new Vue({
  el: '#app',
  router
});

Code snippet from my Dashboard.vue:

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Dashboard Component</div>

                    <div class="card-body">
                        I'm an example component.
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
  export default {
    mounted() {
      console.log('Component mounted.')
    }
  }
</script>

Code snippet from my master.blade.php layout:

//sidebar
<ul>
  <li>
    <router-link to="/dashboard" class="nav-link">Dashboard</li>
  <li>
    <router-link to="/profile" class="nav-link">Profile</li>
</ul>
//content
<div class="container-fluid">
  <router-view></router-view>
</div>

I'm running app at localhost:3000with browserSync and npm run watch. Does it has anything to do with error ?

4 Answers 4

31

Try adding .default to your component requires:

let routes = [{
    path: '/dashboard',
    component: require('./components/Dashboard.vue').default
  },
  {
    path: '/profile',
    component: require('./components/Profile.vue').default
  }
]
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. It worked. Could you please help me understand what your suggested code just did ?
no worries! Glad to help :) - you could also do component: () => import('../components/Test.vue') aswell I believe :)
I'm not sure 100% why it doesn't work without it, just that it has something to do with async components - could you mark my answer as correct please :)
2

While not applicable to the specifics of this question, the error message above can also be encountered when failing to wrap one's HTML in <template>...</template> tags. This would cause vue to not detect a template, as none has been defined via tags or object properties.

For example, within Dashboard.vue, if one were to write (within Dashboard.vue):

<!-- EXAMPLE OF INCORRECT SYNTAX: missing <template> tag -->
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Dashboard Component</div>

                <div class="card-body">
                    I'm an example component.
                </div>
            </div>
        </div>
    </div>
</div>

<script>
  export default {
    mounted() {
      console.log('Component mounted.')
    }
  }
</script>

rather than:

<template> <!-- NOTE THE <template> tag, here -->
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Dashboard Component</div>

                    <div class="card-body">
                        I'm an example component.
                    </div>
                </div>
            </div>
        </div>
    </div>
</template> <!-- NOTE THE </template> tag, here -->

<script>
  export default {
    mounted() {
      console.log('Component mounted.')
    }
  }
</script>

one would receive the error message: Vue.js Failed to mount component: template or render function not defined

Comments

0

// Just add "import Vue from 'vue'" and the component will be shown !

require('./bootstrap');


window.Vue = require('vue');

import VueRouter from 'vue-router'
Vue.use(VueRouter)

let routes = [{
    path: '/dashboard',
    component: require('./components/Dashboard.vue')
  },
  {
    path: '/profile',
    component: require('./components/Profile.vue')
  }
]

const router = new VueRouter({
  routes
})

Vue.component('example-component', require('./components/ExampleComponent.vue'));

const app = new Vue({
  el: '#app',
  router
});

Comments

0

This was bugging me for so long, the change is so small that I could barely notice it in two different router files, among which one works, one doesn't.

Instead of

let routes = [{
    path: '/dashboard',
    component: require('./components/Dashboard.vue')
  }]

you should use

let routes = [{
        path: '/dashboard',
        component:()=> import('./components/Dashboard.vue')
      }]

The point is component property will also accept a function, and in that function, you can return an imported component which will only be called when it is required. If you give require() directly, it is imported immediately.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.