Vue router doesn't route to specified location - javascript

I'm using vue with vue-router and route doesn't work when routing to children route.
{
path: '/user',
name: 'User',
component: User,
children: [
{
path: 'profile',
component: Profile,
},
],
}
Programmatically routing to /user/profile
<template>
<div>
<button #click="goToUserProfile()">create new</button>
</div>
</template>
<script>
export default {
methods: {
goToUserProfile() {
this.$router.push('/user/profile') // Routing doesn't work
.catch(console.log);
},
},
};
</script>

give a route name "Profile" for "/user/profile"
{
path: '/user',
name: 'User',
component: User,
children: [
{
path: 'profile',
name: "Profile",
component: Profile,
},
],
}
navigation use route name
this.$router.push({name: "Profile"});
your User component should declare like this
User.vue
<template>
<div>
<p>this is user component</p>
<!-- your Profile component will replace this route-view -->
<route-view />
</div>
</template>
demo
https://codesandbox.io/s/falling-bash-6dl7m

Do your ensure that you put <router-view></router-view> in User Component template to make the nested (children) routes displayed.
<template>
<div>
<button #click="goToUserProfile()">create new</button>
<router-view></router-view> <!-- placeholder for children routes -->
</div>
</template>
Then you can access by both
this.$router.push('/user/profile') and this.$router.push({ name: 'UserProfile' })
As Vue router document states:
To render components into this nested outlet, we need to use the children option in VueRouter.
https://router.vuejs.org/guide/essentials/nested-routes.html
Hope this help.

Related

Why does every component in my page appears twice?

I have created a sort of First page for my project, but I don't know why it renders everything twice on my page:
here is my First.vue component that is used by the router as the first page:
<template>
<h1>Bienvenue</h1>
<router-view></router-view>
<div class="routing" v-if="this.$route.path == '/'">
<router-link to='/app'>Go to application</router-link>
<br>
<router-link to='/test'>Go to test</router-link>
</div>
</template>
and here is what I get on the page when I npm run serve
Does anyone knows where it comes from?
UPDATE
When I delete the router-view element, the components appear once but when I click on one of the links, it changes the URL of the page but the page in itself is not showing the component.
And when I try to put everything in my router-view, like this:
<template>
<router-view>
<div class="routing" v-if="this.$route.path == '/'">
<h1>Bienvenue</h1>
<router-link to='/app'>Go to application</router-link>
<br>
<router-link to='/test'>Go to test</router-link>
</div>
</router-view>
</template>
it appears once, but like the other case, when I click on a link, it is just changing the URL and not the page.
Here is my index.js to show you how my routes are defined:
import {createRouter, createWebHistory} from 'vue-router'
import App from '../App.vue'
import Test from '../Views/Test.vue'
import First from '../Views/First.vue'
export const router = createRouter({
history: createWebHistory(),
routes: [
{
path:'/',
name: 'First',
component: First,
},
{
path:'/test',
name: 'Test',
component: Test
},
{
path:'/app',
name: 'App',
component: App
}
]
})
Just to clarify what results I expect from my app:
When I run the project, I want to launch on a page with just a header saying 'Hello' at the top of the page and two links where I can either click on 'Go to the application' or 'Go to test'.
Then, when I click on one of the links, I want to see the content of the component (so either test or the app), but I don't want to see the header and the links anymore.
I am not sure but try this:
{
path: "/app",
component: () => import("../App.vue"),
name: "App"
},
{
path: "/test",
component: () => import("../Views/Test.vue"),
name: "Test"
},
{
path: "/",
component: () => import("../Views/First.vue"),
name: "First"
}
Update with sample code or you can refer to live code here.
// App.vue
const First = {
template: `<div class = "container" id="app">
<h1>Hi from First</h1>
<hr>
<router-link to="/foo">Foo</router-link>
<router-link to="/bar">Bar</router-link>
</div>
`
}
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const routes = [
{
path:'/',
name: 'First',
component: First,
default: First
},
{
path:'/foo',
name: 'Foo',
component: Foo
},
{
path:'/bar',
name: 'Bar',
component: Bar
}
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
// main.js
<div id="app">
<!-- route outlet -->
<!-- component matched by the route will render here -->
<router-view></router-view>
</div>

True or False to show route-item in navbar

im building a website and using vvue with vue-router.
My Navbar component iterates through the routes element and gets all routes to show in the navbar, so i can simply add and remove routes without changing the navbar component.
Now i want for example the Data protection notice or the legal notice not to show up.
I tried to solve this with a boolean and a v-if. Do you have any idea how to solve this problem?
My code looks as following:
Navbar component:
<template>
<div>
<div class="mdheader"></div>
<div class="md-layout-item">
<md-tabs md-sync-route class="md-primary" md-alignment="centered">
<div
v-for="r in this.$router.options.routes"
:key="r.name"
:v-if="r.showOnBar"
>
<md-tab :md-label="r.name" :to="r.path" exact></md-tab>
</div>
</md-tabs>
</div>
</div>
</template>
<script>
export default {
name: "navbar"
};
</script>
router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "#/views/Home.vue";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Home",
component: Home,
showOnBar: true
},
{
path: "/about",
name: "About",
showOnBar: true,
component: () => import("#/views/About.vue")
},
{
path: "/aktuelles",
name: "Aktuelles",
showOnBar: true,
component: () => import("#/views/Aktuelles.vue")
},
{
path: "/datenschutz",
name: "Datenschutz",
showOnBar: false,
component: () => import("#/views/Datenschutz.vue")
}
];
const router = new VueRouter({
routes
});
export default router;
Thanks in advance
Youa re very close, but you need to wrap your custom property in meta option:
const routes = [
{
path: "/",
name: "Home",
component: Home,
meta: { showOnBar: true }
},
{
path: "/about",
name: "About",
meta: { showOnBar: true }
component: () => import("#/views/About.vue")
},
{
path: "/aktuelles",
name: "Aktuelles",
meta: { showOnBar: true },
component: () => import("#/views/Aktuelles.vue")
},
{
path: "/datenschutz",
name: "Datenschutz",
meta: { showOnBar: false }
component: () => import("#/views/Datenschutz.vue")
}
];
and access it via route.meta.showOnBar. Keep in mind that you only need to define it for routes you want to show on your navbar.
You need to wrap your custom route properties into meta as stated in BroiSatse's answer.
However, another issue is that you used :v-if (i.e. you bound the v-if attribute) instead of just using v-if. v-if already evaluates the condition in the value as per the docs.
Here's a sandbox to play around with: https://codesandbox.io/s/stack-overflow-q-62409392-6zovw?file=/src/router/index.js

Vue-router nested route not loading my component page

I am using Vue-router and I was needing to use a nested route, so what I did I wrote Children Key word to reference for a child component page, so my problem is when I click on Link my current URL replaced with nested route and with an ID but not load my component, and when I change Router-Linke to another component that is not nested it will load component, so I ask what are my mistakes?
route.js
{
path: '/targets',
name: 'target',
component: () =>
import ( /* webpackChunkName: "target" */ '#/views/admin/Target.vue'),
meta: {
middleware: [
auth
],
title: "Targets"
},
children:[
{
path: '/targets/:id/details',
name: 'target-details',
props: true,
component: () =>
import ( /* webpackChunkName: "target" */ '#/views/admin/TargetDetails.vue'),
meta: {
middleware: [
auth
],
title: "TargetDetails"
}
},
]
},
target.vue
<template>
<div>
<li class="clearfix" v-for="domain in domains" :key="domain.domain_id">{{ domain.domain }}
<router-link class="more"
:to="{
name: 'target-details',
params: {
id: domain.domain_id
}
}" >Target details <i class="fa fa-angle-right"></i>
</router-link>
</li>
</div>
</template>
TargetDetails.vue
<template>
<div class="page-output">
<h1>Target Details</h1>
</div>
</template>
Nested routes are designed to facilitate component nesting (look at the 1st "picture")
You need to include <router-view> in your target.vue component...
If you don't want content of TargetDetails.vue rendered inside target.vue, dont use children config and make a target.vue top level route instead.

How to show children view without router-view parent view in vuejs?

I'm trying to show a child route view in another view and not inside the parent route view,
i have the next routes in an the module of vue-router:
const users = {
path: '/users',
name: 'users',
component: Users,
children: [
{ path: ':user',
name: 'user',
component: User,
children: [
{ path: 'profile', name: 'profile', component: Profile },
{ path: 'events', name: 'events', component: Events }
]
}
]
}
export default home
When entering the path /users/:user shows me the children view inside the parent view through the router-view
<!-- users.vue -->
<!-- path: /users -->
<template>
<div v-if="(user, index) in users" :key="index">
<router-link :to="`/users/${user.name}`">{{ user.name }}</router-link>
</div>
<!-- Here shows the children view -->
<!-- path: /users/:user/ -->
<router-view/>
</template>
I need it to be shown directly in another independent view and not inside the parent view,
It would be something like this:
<!-- users.vue -->
<!-- path: /users -->
<template>
<div v-if="(user, index) in users" :key="index">
<router-link :to="`/users/${user.name}`">{{ user.name }}</router-link>
</div>
</template>
<!-- user.vue -->
<!-- path: /users/:user -->
<template>
<h1>{{ this.$route.params.name }}</h1>
</template>
If you could help me, thank you
regards
Create a separate route for the user route, not the children of users
const users = [{
path: '/users',
name: 'users',
component: Users,
},
{
path: 'users/:user',
name: 'user',
component: User,
children: [
{ path: 'profile', name: 'profile', component: Profile },
{ path: 'events', name: 'events', component: Events }
]
}
]

Vue Router: hide parent template when child is open

Im trying to install Vue.js with the router and im running into some view issues. I have a router.js with child routes. I want to use this method for simple breadcrumbs and generate a clear overview so i know which route belongs where.
Opening each route works like a charm, everything shows up. When i open /apps I get a nice view from my Apps.vue that displays App overview</h1>. But now im opening /apps/app-one and then I see the Apps.vue and AppOne.vue template. How can I prevent that both templates are displayed?
The vue components looks like this:
Router.js
import Router from 'vue-router';
import AppsPage from './components/Apps.vue'
import AppOne from './components/AppOne.vue'
import AppTwo from './components/AppTwo.vue'
export default new Router({
// mode: 'history',
routes: [
{
path: '/apps',
component: AppsPage,
children: [
{
path: '/apps/app-one',
component: AppOne,
},
{
path: '/apps/app-two',
component: AppTwo,
},
]
},
]
});
Apps.vue
<template>
<div id="app-overview">
<h1>App overview</h1>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app_page'
}
</script>
App1.vue
<template>
<div>
<h1>App 1</h1>
</div>
</template>
<script>
export default {
name: 'app_one'
}
</script>
App2.vue
<template>
<div>
<h1>App 2</h1>
</div>
</template>
<script>
export default {
name: 'app_two'
}
</script>
Having your routes in a parent-child relationship means that the child component will be rendered inside the parent component (at the <router-view>). This is expected behavior.
If you do not want the parent component to be visible when the child route is active, then the routes should be siblings, not nested:
[
{
path: '/apps',
component: AppsPage,
},
{
path: '/apps/app-one',
component: AppOne,
},
{
path: '/apps/app-two',
component: AppTwo,
},
]
The structure of the routes reflects the way they are rendered on the page.
It's possible and pretty easy too.You can achieve this by followings:
<template>
<div>
<div v-show="isExactActive">
Parent component contents will be here
</div>
<router-view ref="rv"></router-view>
</div>
</template>
<script>
export default {
data() {
return {
isExactActive: true,
}
},
updated() {
this.isExactActive = typeof this.$refs.rv === 'undefined';
},
mounted() {
this.isExactActive = typeof this.$refs.rv === 'undefined';
}
}
</script>
Hope, this will be helpful.

Categories