javascript - VueJS 3 - <router-link-active> class not applied to routes that start with the same path name - Stack

I have created a simple navar where I have 3 links. All links are declared at a ROOT level of the route

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", ponent: link2 },
{ path: "/link2/sibling", ponent: 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.

Codesandbox

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 "./ponents/link1.vue";
import link2 from "./ponents/link2.vue";
import sibling from "./ponents/sibling.vue";
import link3 from "./ponents/link3.vue";

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: "/", ponent: link1 },
    { path: "/link2", ponent: link2 },
    { path: "/link2/sibling", ponent: sibling },
    { path: "/link3", ponent: 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>

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", ponent: link2 },
{ path: "/link2/sibling", ponent: 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.

Codesandbox

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 "./ponents/link1.vue";
import link2 from "./ponents/link2.vue";
import sibling from "./ponents/sibling.vue";
import link3 from "./ponents/link3.vue";

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: "/", ponent: link1 },
    { path: "/link2", ponent: link2 },
    { path: "/link2/sibling", ponent: sibling },
    { path: "/link3", ponent: 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>
Share Improve this question asked Feb 18, 2022 at 16:42 babis95babis95 6221 gold badge8 silver badges32 bronze badges 1
  • I have this problem to, did you solved it ? – morteza mortezaie Commented Aug 14, 2022 at 14:04
Add a ment  | 

1 Answer 1

Reset to default 5

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 ponent, 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 "./ponents/link1.vue";
import link2 from "./ponents/link2.vue";
import sibling from "./ponents/sibling.vue";
import link3 from "./ponents/link3.vue";

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: "/", ponent: link1 },
    { 
        path: "/link2",
        ponent: link2,
        children: [
            {
              path: 'sibling',
              ponent: sibling
            },
          ]
    },
//    { path: "/link2/sibling", ponent: sibling
//        
//    },
    { path: "/link3", ponent: 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>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745634538a4637309.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信