Search code examples
javascriptvue.jsvue-routervuejs3vue-router4

Vue.js - Component is missing template or render function


In Vue 3, I created the following Home component, 2 other components (Foo and Bar), and passed it to vue-router as shown below. The Home component is created using Vue's component function, whereas Foo and Bar components are created using plain objects.

The error that I get:

Component is missing template or render function.

Here, the Home component is causing the problem. Can't we pass the result of component() to a route object for vue-router?

<div id="app">
   <ul>
      <li><router-link to="/">Home</router-link></li>
      <li><router-link to="/foo">Foo</router-link></li>
      <li><router-link to="/bar">Bar</router-link></li>
   </ul>
   <home></home>
   <router-view></router-view>
</div>

<script>
   const { createRouter, createWebHistory, createWebHashHistory } = VueRouter
   const { createApp } = Vue
   const app = createApp({})

   var Home = app.component('home', {
      template: '<div>home</div>',
   })

   const Foo = { template: '<div>foo</div>' }
   const Bar = { template: '<div>bar</div>' }

   const router = createRouter({
      history: createWebHistory(),
      routes: [
        { path: '/', component: Home },
        { path: '/foo', component: Foo },
        { path: '/bar', component: Bar },
      ],
    })

    app.use(router)

    app.mount('#app')
</script>

See the problem in codesandbox.


Solution

  • When app.component(...) is provided a definition object (the 2nd argument), it returns the application instance (in order to allow chaining calls). To get the component definition, omit the definition object and provide only the name:

    app.component('home', { /* definition */ })
    const Home = app.component('home')
    
    const router = createRouter({
      routes: [
        { path: '/', component: Home },
        //...
      ]
    })
    

    demo