Failed to mount component: template or render function not defined - vue.js

I'm trying to use vue-router to display routed components below my navbar component but I get an error specified in the title.
Here is my code:
main.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import app from './app';
Vue.use(VueRouter);
const foo = {
template: '<div>foo</div>',
};
const bar = {
template: '<div>bar</div>',
};
const routes = [
{
path: '/',
component: foo,
},
{
path: '/bar',
component: bar,
},
];
const router = new VueRouter({
mode: 'history',
routes,
});
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(app),
});
app.vue
<template>
<div id="app">
<fs-navbar/>
<main>
<router-view/>
</main>
</div>
</template>
<style scoped lang="scss">
</style>
<script>
import fsNavbar from './components/fs-navbar';
export default {
components: {
fsNavbar,
},
};
</script>
components/fs-navbar.vue
<template>
<nav>...</nav>
</template>
<style scoped lang="scss">
</style>
<script>
import Vue from 'vue';
export default Vue.component('fs-navbar', {
// logic
});
</script>
This app causes an error:
vue.js?3de6:2574[Vue warn]: Failed to mount component: template or render function not defined. (found in component <fs-navbar>)
If I add fs-navbar template directly into app.vue's template everything is working as intended. Without router app is working as well.
I'm using vue-cli with this template(vuejs2)

Smilar problem, when I write:
let routes = [{
path: '/',
component: require('./components/member.vue')
}]
it failed:[Vue warn]: Failed to mount component: template or render function not defined.
add ".default", it works!
let routes = [{
path: '/',
component: require('./components/member.vue').default
}]
PS:"vue": "^2.5.2","vue-router": "^3.0.1""vue-loader": "^13.3.0",
https://github.com/vuejs/vue-loader/releases/tag/v13.0.0

Turns out, that Vue.component() return value isn't working with the router.
When changed:
export default Vue.component('component-name', {})
to:
export default {}
Everything is working fine.

Related

Why do my Vue-router doesnt route to my pages?

I got my Vue.js application, i've installed vue-router, via npm i vue-router,
i got a router-link on my main page App.vue, and i want to redirect to my Inscription.vue.
I do go on the http://localhost:8080/inscription when i click on the router-link, but the view doesnt change, im still on my main page,
i don't understand why ? (i got no error)
My main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App)
}).$mount('#app')
Vue.use(router);
My router/index.js :
import Vue from 'vue'
import Router from 'vue-router'
import App from '../App.vue'
import Inscription from '../Inscription.vue'
Vue.use(Router)
const routes = [
{
path: '/',
name: 'Home',
component: App
},
{
path: '/inscription',
name: 'Inscription',
component: Inscription
}
]
const router = new Router({
mode: 'history',
routes: routes
});
export default router;
My App.vue simplified
<template>
<div class="acceuil_main">
<div class="navbar_element">
<router-link :to="{name: 'Inscription'}">Inscription</router-link>
</div>
</div>
</template>
<script>
export default {
name: "App",
data () {
return {
beers: null,
connected: false,
user: null
}
}
};
</script>
My Inscription.vue simplified
<template>
<div class="acceuil_main">
<a class="navbar_element">
Inscription
</a>
</div>
</template>
<script>
export default {
name: "Inscription",
data () {
return {
title: "Inscription",
connected: false,
user: null
}
}
};
</script>
a picture of my folder architecture
For router to actually work you need a <router-view> component somewhere in your app. The best place is probably the App component. Check the docs
<router-view> works as a placeholder - router put there the component configured for a route when the route is active.
In that sense your / route should probably not use App component but something else - create another component for example Home which will be displayed on the root route (/)
const App = Vue.component('App', {
name: "App",
template: `
<div class="acceuil_main">
<div class="navbar_element">
<router-link :to="{name: 'Inscription'}">Inscription</router-link>
</div>
<router-view></router-view>
</div>
`
})
const Inscription = Vue.component('Inscription', {
template: `
<div>Inscription</div>`
})
const routes = [{
path: '/inscription',
name: 'Inscription',
component: Inscription
}]
const router = new VueRouter({
mode: 'history',
routes: routes
});
new Vue({
router,
render: h => h(App)
}).$mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>

Vue Router import not working with require

I'm setting up a brand new Vue 2 project. Due to compatibility issues with one of the libraries I need to use, I can't yet move to Vue 3.
I have a very basic setup at the moment, folder structure something like this:
/
App.vue
main.js
router.js
/pages
AboutUs.vue
Home.vue
If I don't use Vue Router, and just import the AboutUs page into App.vue and call its tag in the template, it displays as expected.
When I instead use the Vue Router to render it in the <router-view /> tag in App.vue, I get the error message:
[Vue warn]: Failed to mount component: template or render function not defined.
I suspect that means I'm doing something wrong in the router but I can't see what.
main.js
import Vue from 'vue'
import App from './App.vue'
import router from 'router.js'
new Vue({
render: h => h(App),
router
}).$mount('#app')
App.vue
<template>
<div id="app">
<router-link to="/">Home</router-link>
<router-link to="/About">About</router-link>
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
router.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const About = require('../pages/AboutUs')
const Home = require('../pages/Home')
const routes = [
{
path: '/about',
name: 'About',
component: About
},
{
path: '*',
name: 'Home',
component: Home
}
]
const router = new VueRouter({
linkExactActiveClass: '',
routes
})
export default router
About.vue
<template>
<div>
<h1>About</h1>
</div>
</template>
<script>
export default {
}
</script>
es6 import
Try to use an es6 import instead of require:
import About from '../pages/AboutUs'
import Home from '../pages/Home'
Then your route syntax will work as is. This is because when you use require, you get the whole module rather than the Component export from the module.
-or-
require
Alternatively, if you wanted to continue using require, you would need the following syntax, using the default property of the module:
const About = require('../pages/AboutUs')
const Home = require('../pages/Home')
const routes = [
{
path: '/about',
name: 'About',
component: About.default
},
{
path: '*',
name: 'Home',
component: Home.default
}
]

Can't see named routes

I'm sure i'm doing something stupid, but i just can't get this to work.
I defined routes in a separate js file, imported that into a newly created router, that i mounted in vue.
In the vue devtools i do see my named routes, but where the RouterView is in the vue devtools, the html shows
Routes.js:
import Home from '#/Views/Home.vue';
import NewProefwerk from '#/Views/NewProefwerk.vue';
const routes = [
{
path: '/',
name: 'home',
Component: Home
},
{
path: '/Nieuw',
name: 'new',
Component: NewProefwerk
}
];
export default routes;
main.js:
import VueRouter from 'vue-router';
import routes from '#/Routes'
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
base: '/',
routes
})
new Vue({
router,
render: h => h(App)
}).$mount('#app');
App.vue:
<template>
<div id="app">
<Navigation></Navigation>
<router-view></router-view>
</div>
</template>
<script>
import Navigation from '#/components/Navigation.vue';
export default {
name: 'app',
components: {
Navigation
}
};
</script>
Try to change Component to component.

Using vue-router programmatically

I'm having issues when trying to use vue-router programatically.
When I use <router-link> in my HTML it works no problem but as soon as I try to use this.$router.push I have no luck. Below is a minimum viable snippet.
main.js
import Vue from 'vue';
import App from './App';
import router from './router';
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
});
router index.js
import Vue from 'vue';
import Router from 'vue-router';
// Pages
import Home from '#/components/pages/Home';
import CalculatorSuite from '#/components/pages/calculator-suite/CalculatorSuite';
Vue.use(Router);
export default new Router({
routes: [
{ path: '/', name: 'Home', component: Home },
{ path: '/calculator-suite', component: CalculatorSuite},
],
});
App.vue
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
};
</script>
Home.Vue
<template>
<div class="home-parent">
// Works
<router-link to="/calculator-suite">Test</router-link>
//Doesn't work
<button :onClick="change">Test</button>
</div>
</template>
<script>
export default {
name: 'Home',
methods: {
change() {
// Do stuff before changing
this.$router.push('/calculator-suite');
},
},
};
</script>
What can I do to allow this to work?
You have a problem on the listener of "click" event. You are biding a value when you should be doing #click instead of :onClick to listen to the click event.
More info about binding: https://v2.vuejs.org/v2/guide/forms.html#Basic-Usage
More info about event handling: https://v2.vuejs.org/v2/guide/events.html
Instead of onclick you need to replace it with #click or v-on:click like as below
<button #click="change">Test</button> // shorthand
or
<button v-on:click="change">Test</button>
You can also use href tag to go to desired page.like as below
<button>Test</button>

Vue-router can't render component correctly with Element-UI

I am trying to use Vue-router with Element-UI( http://element.eleme.io/#/en-US/component/quickstart ). But I face some weird condition. Following is my app.js, where I create my vue-router instance.
import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import ElementUI from 'element-ui'
import locale from 'element-ui/lib/locale/lang/zh-TW'
import 'element-ui/lib/theme-default/index.css'
import myComponent from './vue/page/mycomponent.vue'
import App from './vue/app.vue'
Vue.use(VueRouter)
Vue.use(Vuex)
Vue.use(ElementUI, {locale})
const router = new VueRouter({
routes: [
{path: '/mypage', component: myComponent}
],
})
const app = new Vue({
router: router,
store: store,
el: '#v-app',
render: h => h(App),
})
And I put my router-view tag in app.vue .
<template lang="pug">
#v-app
v-sidebar(:pages="pages")
router-view
</template>
<script>
import Sidebar from './sidebar.vue'
export default {
name: 'App',
data() {
return {
pages: [],
}
},
components: {
'v-sidebar': Sidebar,
},
}
</script>
<style lang="sass" scoped>
</style>
Here is my router-link in sidebar.vue.
<template lang="pug">
#sidebar
template(v-for="page in pages")
router-link(:to="{path: page.prop}")
i(class="chevron right icon")
span {{page.label}}
</template>
<script>
export default {
name: 'Sidebar',
data() {
return {
defaultProps: {
label: 'label',
children: 'children',
},
pages:[{label: 'link-1', prop: 'mypage'}]
}
},
}
</script>
If I strictly go to "/mypage" then it will render correctly. But if I click the link in my sidebar component, the page component won't render completely. I am wonder if there is somewhere I missed or what should I do to fix this kind of situation.