Nav items having active class even when I change - vue.js

I am facing this issue with navigation. Whenever I switch the tabs, the route with "" keeps being active all the time no matter what. I tried using router-exact css, but whenever I go in nested route then the menu nav stops having active class. I believe this is because the path is ""
Router:
{
path: "",
name: "Item1",
component: Item
}
Component
<router-link :to="{ name: 'Item1' }" >Item1</router-link>
<router-link :to="{ name: 'Item2' }" >Item2</router-link>
<router-link :to="{ name: 'Item3' }" >Item3</router-link>
The lighter color is active class
How it looks

Set path to '/' and add exact or exact-path to links: <router-link exact :to="{...}">
Here is the official documentation: https://router.vuejs.org/api/#exact

Related

How to increment VueJS Router Link ID by 1?

I have
<router-link
:to="{ name: 'painting', params: { id: parseInt(this.id) + 1 } }"
>Next</router-link
>
I thought I could go to the same path + 1.
The URL changes to + 1 (at first click only). But the page won't reload.
If I check on the second time, the href is still the same ID, it doesn't add 1. I imagine is because it won´t reload.
Here´s my router specs:
{ path: "/painting/:id?", name: "painting", component: Painting }
Now I´ve tried:
<router-link
:to="{
name: 'painting',
params: { id: Number(this.$route.params.id) + 1 },
}"
>Next</router-link
>
And the URL changes, but the doesn´t.
Used
<router-view :key="$route.fullPath"></router-view>

What would be the best way to use vue routes?

I'm a bit new to Vue routes. I have a table in Home.vue and each row has a button in order to go to the details. I'll try to explain what I imagine. I want the redirection to open a new screen Overview with a sidebar that has 3 options: Overview, Commits and Files. My problem is to understand what should be the parent and what should the child. I'm sure that Commits and Files are children but should Overview be also a child or the parent of Commits and Files? The row that redirects to details:
<router-link :to="{ 'name': 'details', 'params': { 'tool': tool } }">{{id}}</router-link>
The routes that I currently have:
const DetailsChildren = [
{
path: 'commits/:tool',
name: 'commits',
component: commits
},
{
path: 'files/:tool',
name: 'files',
component: files
}
];
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home
}
{
path: '/overview/:tool',
name: 'details',
component: details,
children: DetailsChildren
}
],
mode: 'history'
});
And DetailsChildren is as follows:
<template>
<div class="main">
<sidebar />
<router-view />
</div>
</template>
Currently DetailsChildren is Overview. But I think DetailsChildren should be the parent of Overview, Files and Commits and then I need to create another component Overview. But then I have two problems. First one is how I load Overview when I move from the table to DetailsChildren? The second one is that I want the route to be /overview/:tool. I'm a bit confused. What would be best way to handle the routes in this situation?
What you want to do is have three children under your details route, each with their own absolute path from /.
const DetailsChildren = [
{
path: '/overview/:tool',
name: 'overview',
component: overview
},
{
path: '/commits/:tool',
name: 'commits',
component: commits
},
{
path: '/files/:tool',
name: 'files',
component: files
}
];
This will create the following path mappings
/overview/:tool
Top-level component: details
Child component: overview
/commits/:tool
Top-level component: details
Child component: commits
/files/:tool
Top-level component: details
Child component: files
See the guide on Nested Routes.
You may think you can use an empty path for the overview route but this would then require the URL to have a trailing slash (ie /overview/tool/) and I figured you don't want that.
It's also recommended to remove the name from your details route and instead, link to the default child route (ie overview). Eg
<router-link :to="{ name: 'overview', params: { tool } }">{{id}}</router-link>
Otherwise, the router gets confused about which to display, the parent (empty) or child.
Your sidebar links can simply use the child route names to create their links, eg
<nav>
<ul>
<li>
<router-link :to="{name: 'overview'}">Overview</router-link>
</li>
<li>
<router-link :to="{name: 'commits'}">Commits</router-link>
</li>
<li>
<router-link :to="{name: 'files'}">Files</router-link>
</li>
</ul>
</nav>

Vue Router does not redirect to the right page

When I try to push a new profile with an profileID with VueRouter I get an error saying: Avoided redundant navigation to current location: "/user/ID". When clicking on the button it is not redirecting me to another page, it just jumps to the beginning of the current page.
I declared my routes in my index.js file like this:
const routes = [
{
path: '/',
name: 'EntryPoint',
component: EntryPoint
},
{
path: '/main',
name: 'Main',
component: Main
},
{
path: '/user/:id',
name: 'User Current',
component: CurrentUser
},
When I am on an user page the path in the url already contains an userID - so f.e. #/user/1111.
Now on the same user page I want to navigate to another user when the user clicks on a button:
<ContactCard
v-for="user in users"
#goToUser="goToUser(user.id)"
/>
goToUser(userId) {
this.$router.push({ name: "User Current", params: { id: userId } });
},
The id which I get from my users array contains different id´s for each user.
Any suggestions why the routing is not working properly?
When clicking on the button I see for an instance that the url is changing with the right path: #/user/1112. Inseatd of updating the page it removes the url, jumps to top and gives me the error message from above when selecting the button again.
When I log
console.log(this.$route.path);
on button click I get the correct route - /user/ID but it is not updating anything.
UPDATE:
As Zdravko Pernikov suggested I keyed my and it works:
<template>
<div id="app">
<div id="nav">
<label>Welcome</label>
<router-link to="/main">Welcome</router-link>
<router-link to="/User">User</router-link>
</div>
<router-view :key="$route.path"/>
</div>
</template>
This may happen because you are reusing your CurrentUser component and you are not listening for changes since it's already rendered.
You can try keying your global router view <router-view :key="$route.path"></router-view> your components will be rerendered on different routes.

Rendering VUE router links with v-for

i want to create an app that renders links dynamically with v-for and opens different components with each link.
I know how to render the <router-link> itself ,But I don't know how to dynamically change the destination url of the to="" prop.
If your array looks for example like this:
components: [
{
path: "/a",
name: "Component A"
},
{
path: "/b",
name: "Component B"
}
]
You can use it in v-for like:
<router-link
v-for="(comp, i) in components"
:key="i"
:to="{ path: comp.path }"
>
{{comp.name}}
</router-link>
You can achieve this using bind :to="{path: '/to'}" in <router-link>.

Router Link only updates active class once

I am trying to use <b-nav-item> tags as router links but the active link class only updates one time – I can load the page and click on a nav item and the class changes appropriately. But clicking again does not.
I have tried various syntax for the link attributes including:
to="dashboard"
to="/dashboard"
:to="{ name: 'Dashboard' }"
:to="{ path: '/dashboard' }"
I've also tried adding the exact attribute tag. Nothing is working and I feel like I'm running in circles here. Any ideas?
CompanionNavigation:
<template>
<div>
<b-nav pills>
<b-nav-item :to="{ name: 'Dashboard'}" exact>Dashboard</b-nav-item>
<b-nav-item :to="{ name: 'Contacts' }" exact>Contacts</b-nav-item>
</b-nav>
</div>
</template>
Routes:
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard,
},
{
path: '/contacts',
name: 'Contacts',
component: Contacts,
},
This was resolved by removing the following from my main template file:
<!-- Load Vue followed by BootstrapVue -->
<script src="//unpkg.com/vue#latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>