Reputation: 53
I'm building a Nuxt app and am having trouble with conditional styling. What I'm trying to do is apply a different background color to the active link depending on what page it is. I know I can use .nuxt-link-exact-active
to style the active link, but I'm stuck on how to make that different on each page.
I have the links in a component that gets rendered on each page. I've tried using .nuxt-link-exact-active
at the page level, but it doesn't get picked up.
Here's what I've got so far, which does change the styling depending on the page, but it does it for all the links, and I only want it on the active link. Please let me know if I can clarify anything. Thanks!
<template>
<nav class="flex-container flex-column mt-1">
<NuxtLink to="/about" class="link" :class="classObject">about</NuxtLink>
<div class="mt-1 flex-container">
<NuxtLink to="/projects" class="link" :class="classObject"
>projects</NuxtLink
>
</div>
<div class="mt-1 flex-container">
<NuxtLink to="/contact" class="link" :class="classObject"
>contact</NuxtLink
>
</div>
</nav>
</template>
<script>
export default {
// apply current route name as a class to the matching div
computed: {
classObject() {
return {
about: this.$route.name === 'about',
projects: this.$route.name === 'projects',
contact: this.$route.name === 'contact',
}
},
},
}
</script>
<style lang="scss" scoped>
.about {
background-color: $near-white;
}
.projects {
background-color: $blue;
}
.contact {
background-color: $yellow;
}
</style>
illustration of what I'm trying to do
Upvotes: 1
Views: 6427
Reputation: 51
I think the easiest way to check if the path is active or not is $nuxt.$route.path.
<template>
<ul>
<li>
<nuxt-link :to="links[0].path" :class="{'bg-black text-white': links[0].path == path }">{{ links[0].name }}</nuxt-link>
<nuxt-link :to="links[1].path" :class="{secondStyle: links[1].path == path }">{{ links[1].name }}</nuxt-link>
</li>
</ul>
</template>
<script>
export default {
name: "Header",
data() {
return {
path: null,
links: [
{path: "/link1", name: "Link 1"},
{path: "/link2", name: "Link 2"}
],
};
},
mounted() {
this.path = $nuxt.$route.path;
},
};
</script>
Upvotes: 0
Reputation: 53
I came up with a solution— not sure if it's the best way, but it works. Each link is now preceded by a div
that only gets rendered on the corresponding page, otherwise a link is rendered.
<template>
<nav class="flex-container flex-column mt-1">
<div v-if="currentPageName === 'about'" class="box about">
<h2>about</h2>
</div>
<div v-else>
<NuxtLink to="/about" class="link">about</NuxtLink>
</div>
<div v-if="currentPageName === 'projects'" class="box projects">
<h2>projects</h2>
</div>
<div v-else>
<NuxtLink to="/projects" class="link">projects</NuxtLink>
</div>
<div v-if="currentPageName === 'contact'" class="box contact">
<h2>contact</h2>
</div>
<div v-else>
<NuxtLink to="/contact" class="link">contact</NuxtLink>
</div>
</nav>
</template>
<script>
export default {
computed: {
currentPageName() {
return this.$route.name
},
},
}
</script>
<style lang="scss" scoped>
.box {
width: 150px;
height: 150px;
}
.about {
background-color: $near-white;
}
.projects {
background-color: $blue;
}
.contact {
background-color: $yellow;
}
</style>
Upvotes: 0
Reputation: 2244
Instead of changing .nuxt-link-exact-active
at the page level, change it in the layout.
So for example, in layouts/default.vue
:
<style>
.nuxt-link-exact-active {
background: red;
}
</style>
Upvotes: 1