How to target router-link-active class in element?

I have a component with 2 router links. I want both to be colored when either one is clicked. Problem is that these router links don't share a router-link-active class, so I'm trying to target them via querySelector and apply the color css property manually.

This is the component:

<template>
  <div id="nav-link-cms" class="nav-link-cms">
    <li>
      <router-link class="router-link" :to="{ name: link}">
      <span>
        <fa class="icon" :icon="icon"></fa>
        <span class="label">{{ label }}</span>
        <router-link class="plus-link" v-if="plusLink" :to="{ name: plusLink }">
          <fa class="icon-plus" :icon="[ 'fas', 'circle-plus' ]"></fa>
        </router-link>
      </span>
      </router-link>
    </li>
  </div>
</template>

and I can target one router-link class plus-link like so:

<script setup>
import { onMounted } from 'vue';

onMounted(() => {
    console.log(document.querySelector('.plus-link'))
})
</script>

This seems to work fine. The browser console outputs:

enter image description here

As you can see both router-link-active and plus-link classes are present in the link element.

Outputting the classList like so:

onMounted(() => {
    console.log(document.querySelector('.plus-link').classList)
})

shows this in the console:

DOMTokenList ['plus-link', value: 'plus-link']
0: "router-link-active"
1: "router-link-exact-active"
2: "plus-link"
length: 3
value: "router-link-active router-link-exact-active plus-link"
[[Prototype]]: DOMTokenList

But as soon as I try to see if the list contains a the router-link-active class:

onMounted(() => {
    console.log(document.querySelector('.plus-link').classList.contains('router-link-active'))
})

the console shows:

false

Is router-link-active applied even after onMounted? How can I target it?

Upvotes: 2

Views: 4476

Answers (1)

Lightning00Blade
Lightning00Blade

Reputation: 175

Have not tried it myself but you should be able to use useLink Docs, from Vue-Router to get if the value for each route (link and plusLink), and then look at the isActive property of both of them then pass it to the template.

Psudo-code:

<template>
 <router-link :class="{active: isActive}" :to="link">
  <router-link :to="plusLink"></router-link>
 </router-link>
</template>
<script setup>
import { RouterLink, RouterView } from "vue-router";
import { ref, watch } from "vue";
import { useLink } from "vue-router";

const isActive = ref(false);
const linkState = useLink({ to: "about" });
const linkPlusState = useLink({ to: "new" });
watch([linkState.isActive + linkPlusState.isActive], () => {
  if (linkState.isActive || linkPlusState.isActive) {
    isActive.value = true;
  } else {
    isActive.value = false;
  }
});
</script>

Note: As a general thing you should avoid direct DOM manipulation when using any FE framework.

Upvotes: 2

Related Questions