Vue.js vue-router issue using navigation guard - vue.js

I am trying to use a navigation guard w my router... when I use it the App component is displayed ( the navigation header) but the child HomePage component is not displayed... If I get rid of the navigation guard, no problem App and HomePage components are well displayed
what's wrong with my navigation guard usage in this case ?
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '#/pages/HomePage'
import ShoppingLists from '#/pages/ShoppingListsPage'
Vue.use(Router)
const router = new Router({
// HTML5 mode history
mode: 'history',
routes: [
{
path: '/',
name: 'Home',
component: Home,
meta: { title: 'Home' }
},
{
path: '/shoppinglists',
name: 'ShoppingLists',
component: ShoppingLists,
meta: { title: 'Shopping Lists' }
}
]
})
router.beforeEach(function (to, from, next) {
if (to.meta && to.meta.title) {
document.title = to.meta.title
}
})
export default router
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
/* eslint-disable no-new */
new Vue({
el: 'app',
router,
components: { App }
})
App.vue
<template>
<div id="app">
<ul class="navigation">
<li id="home"><router-link :to="{ name: 'Home' }" >Home</router-link></li>
<li id="shoppinglists"><router-link :to="{ name: 'ShoppingLists' }" >Shopping Lists</router-link></li>
</ul>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
HomePage.vue
<template>
<div class="hello">
<img src="./../assets/logo.png">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'Hello',
data () {
return {
msg: 'Welcome to our ShoppingList app'
}
}
}
</script>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>shopping-list</title>
<link rel="shortcut icon" type="image/png" href="/static/favicon.ico"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<app></app>
<!-- built files will be auto injected -->
</body>
</html>

You have forgotten to add next().
router.beforeEach(function (to, from, next) {
if (to.meta && to.meta.title) {
document.title = to.meta.title
next()
}
next()
})

Related

[Vue warn]: invalid template option:

I'm using vue router to load components. The Home & About components load fine in the browser but the Login component fails to load and returns the error above.
resources/js/components/LoginComponent.vue
<template>
<div>
<h1>login</h1>
</div>
</template>
<script>
export default {}
</script>
resources/js/app.js
import './bootstrap';
import LoginComponent from "./components/LoginComponent.vue";
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/login', component: LoginComponent } // edited
]
const router = VueRouter.createRouter({
// 4. Provide the history implementation to use. We are using the hash history for simplicity here.
history: VueRouter.createWebHashHistory(),
routes, // short for `routes: routes`
})
// 5. Create and mount the root instance.
const app = Vue.createApp({})
app.use(router)
app.mount('#app')
app.blade.php
<body>
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- use the router-link component for navigation. -->
<!-- specify the link by passing the `to` prop. -->
<!-- `<router-link>` will render an `<a>` tag with the correct `href` attribute -->
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
<router-link to="/login">Go to Login</router-link>
</p>
<!-- route outlet -->
<!-- component matched by the route will render here -->
<router-view></router-view>
Can you spot anything obvious as I'm stumped at the moment?
Edit:
For the correct usage of my particular versions of vue & vue-router
resources/js/app.js
import LoginComponent from "./components/LoginComponent.vue";
import './bootstrap';
const Home = { template: '<div>Home</div>' }
const routes = [
{ path: '/', component: Home },
{ path: '/login', name: "Login", component: LoginComponent },
]
resources/views/layouts/app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Scripts -->
#vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head>
<body>
<div id="app">
<p>
<router-link to="/">Go to Home</router-link>
<router-link to="/login">Login</router-link>
</p>
<router-view></router-view>
</div>
<script src="https://unpkg.com/vue#3"></script>
<script src="https://unpkg.com/vue-router#4"></script>
</body>
</html>

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>

How to use vue-router-next without bundler?

The previous version of vue-router uses the global application instance and mounts the plugin automatically:
if (inBrowser && window.Vue) {
window.Vue.use(VueRouter);
}
Now this possibility was restricted in Vue 3 version. So, how I should get VueRouter to pass to app.use(VueRouter) if I use CDN instead of bundler in vue-router-next?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="https://unpkg.com/vue#next"></script>
<script src="https://unpkg.com/vue-router#next"></script>
<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>
<router-view></router-view>
</div>
<script>
const { createRouter, createWebHistory, createWebHashHistory } = VueRouter
const { createApp } = Vue
const 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 },
],
})
const app = createApp({})
app.use(router)
window.vm = app.mount('#app')
</script>
</body>
</html>
Credits to posva

I can not move another path in Vue JS

Im new to Vue JS and I'm making a simple page in Vue JS. Here are my codes:
main.js
import Vue from 'vue'
import App from './App.vue'
import PokeProfile from './components/PokeProfile.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import VueRouter from 'vue-router';
Vue.use(VueRouter)
Vue.use(ElementUI)
const router = new VueRouter({
routes: [
{path: '/', component: App},
{path: '/pokemon/:id', component: PokeProfile},
],
mode: 'history'
})
//Vue.config.productionTip = false
new Vue({
el: '#app',
render: h => h(App),
router: router
})
App.js
<template>
<div id="app">
<div class="tag-group">
<el-tag
v-for="pokemon in pokemons"
:key="pokemon.national_id"
:type="pokemon.name"
effect="plain">
<poke-item :pokemon=pokemon></poke-item>
</el-tag>
</div>
</div>
</template>
<script>
import PokeItem from './components/PokeItem.vue'
import axios from 'axios'
export default {
name: 'app',
components: {
PokeItem
},
data() {
return {
pokemons: []
}
},
created() {
axios.get("http://localhost:3000")
.then(res => this.pokemons = res.data)
.catch(err => {console.log(err)})
}
}
</script>
<style>
div {
display: flex;
justify-content: center;
}
</style>
PokeItem.js
<template>
<div>
<router-link :to="pokemonLink">
{{pokemon.name}}
</router-link>
</div>
</template>
<script>
export default {
data() {
return {}
},
props: {
pokemon: {
type: Object,
required: true
}
},
computed: {
pokemonLink() {
return `/pokemon/${this.pokemon.national_id}`
}
}
}
</script>
PokeProfile.js
<template>
<h1>Hello Pokemon</h1>
</template>
<script>
export default {
}
</script>
The problem here is I can not move to PokeProfile.js when I click on an item in the PokeItem.js file. What could be the problem? I've checked the section of the code related to routing but I didn't see any problem.
Vue-Router uses a dynamic component (<router-view>) to render the components of your routes. Usually you will find this component in the template of your app.vue. Since you have no <router-view> component Vue-Router does not know where to render your route components.
Try this:
// main.js
import Home from './components/Home.vue'
const router = new VueRouter({
routes: [
{path: '/', component: Home},
{path: '/pokemon/:id', component: PokeProfile},
],
mode: 'history'
})
// components/Home.vue
// your old App.vue
// ./App.vue
<template>
<main>
<router-view></router-view>
</main>
</template>

Vue 2.0 router view doesn't work when used in webpack 2

When I click foo, the console would print as expected, but the <router-view> render nothing.
The offical docs only display how to use it in a single html file and javascript code is embeded directly in it. I've read many examples but I can't make it in webpack.
Or is there any example about vue 2 router in webpack?
I create app.vue file as a layout:
<template>
<div id="app">
<h1>Hello App!</h1>
<p>
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<router-view></router-view>
</div>
</template>
<script>
export default {
}
</script>
and webpack entry file:
import Vue from 'vue';
import VueRouter from 'vue-router'
import VueResource from 'vue-resource'
Vue.use(VueResource)
Vue.use(VueRouter)
import appView from 'app.vue'
const Foo = { template: '<div>foo</div>' , mounted(){console.log(this,'mount foo')}}
const Bar = { template: '<div>bar</div>' }
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
const router = new VueRouter({
routes
})
new Vue({
router,
render (h) {
return h(appView);
},
}).$mount('#app')
the html file:
<!DOCTYPE html>
<html lang='zh'>
<head>
</head>
<body>
<div id="app">
</div>
<script type="text/javascript" src="/static/bunlde.js"></script>
</body>
</html
In case others fall in this trap like me. In your webpack 2 config file, add:
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},