Reputation: 622
I have created a simple navar where I have 3 links. All links are declared at a ROOT level of the router object. I've added a simple styling targeting the <router-link-active>
class where the active link is highlighted on the navbar. This all works fine, switching between links updates the URL, changes the <router-view>
as well as applies correct style to the navbar link currently on.
The issue I'm having is that whenever I click on a 4th link which is also declared on the ROOT level of the router object, starting with the same path name as currently active link, the <router-link-active>
class disasters. e.g.
{ path: "/link2", component: link2 },
{ path: "/link2/sibling", component: sibling },
My understanding is because the /links2/sibling
starts with the same name as /link2
, the navbar item that navigates to /link2
should still be have the <router-link-active>
class, even when the /link2/sibling
is currently active URL.
App.vue
<template>
<div>
<ul class="flex gap-x-5">
<router-link to="/">
<li>Link 1</li>
</router-link>
<router-link to="/link2">
<li>Link 2</li>
</router-link>
<router-link to="/link3">
<li>Link 3</li>
</router-link>
</ul>
</div>
<router-view />
</template>
<script>
export default {
name: "App",
};
</script>
<style>
a:hover,
a:active,
a.router-link-active {
color: #f1a80a;
border-color: #f1a80a;
background-color: #1a037e;
}
</style>
main.js
import App from "./App.vue";
import router from "./router.js";
const app = createApp(App);
app.use(router);
app.mount("#app");
router.js
import { createRouter, createWebHistory } from "vue-router";
import link1 from "./components/link1.vue";
import link2 from "./components/link2.vue";
import sibling from "./components/sibling.vue";
import link3 from "./components/link3.vue";
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/", component: link1 },
{ path: "/link2", component: link2 },
{ path: "/link2/sibling", component: sibling },
{ path: "/link3", component: link3 }
]
});
export default router;
link1.vue
<template>
<div>You are inside Link1</div>
</template>
link2.vue
<template>
<div>
<router-link to="/link2/sibling">
You are inside Link 2 (CLICK ME)
</router-link>
</div>
</template>
link3.vue
<template>
<div>You are inside Link 3</div>
</template>
sibling.vue
<template>
<div>You are inside Link2 sibling</div>
</template>
Upvotes: 7
Views: 3690
Reputation: 1966
I think that is the natural behavior that we could expect from routing. when you click on You are inside Link 2 (CLICK ME)
inside link2.vue
component, the vue-router
loads sibling.vue
in the router-view
part in your App.vue
. So there is no You are inside Link 2 (CLICK ME)
link in that view to see the router-link-active
styles. If you want to see that styles, you must keep your link in the view and don't allow vue-router
to disappear that.
For achieving such a goal you can use Nested Routes in vue-router
like this. First change your router.js file to something like this:
import { createRouter, createWebHistory } from "vue-router";
import link1 from "./components/link1.vue";
import link2 from "./components/link2.vue";
import sibling from "./components/sibling.vue";
import link3 from "./components/link3.vue";
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/", component: link1 },
{
path: "/link2",
component: link2,
children: [
{
path: 'sibling',
component: sibling
},
]
},
// { path: "/link2/sibling", component: sibling
//
// },
{ path: "/link3", component: link3 }
]
});
export default router;
And then add a <router-view>
to your link2.vue
file like this:
<template>
<div>
<router-link to="/link2/sibling">
You are inside Link 2 (CLICK ME)
</router-link>
<router-view></router-view>
</div>
</template>
Upvotes: 5