vuejs <router-link> component keeps the link to the root path always active - vue.js

I have my navigation like this
<nav>
<ul class="nav nav-list">
<router-link tag="li" to="/">Home</router-link>
<router-link tag="li" to="/page1">Page1</router-link>
<router-link tag="li" to="/page2">Page2</router-link>
</ul>
</nav>
I want the link to Page1 to be active when ever am in page1 and same for Page2. It is working fine, the links are been activated when I navigate to the pages BUT the problem is that to link to the root (/) page is always active even when I leave the page.

The root link is always active, because Vue Router partially matches the root / path with the current path.
To perform an exact match you can either:
Add an exact attribute to the router-link:
<router-link tag="li" to="/" exact>
<a href="#">
Home
</a>
</router-link>
Set your active class in the linkExactActiveClass router constructor option instead of linkActiveClass.

Related

Nuxt.js 3 and on-site anchor navigation

I am learning Nuxt.js 3 and am writing a simple project with a one-scroll design that has a menu with anchor links. Clicking a link, the site should automatically scroll to the anchor (like a div with an id).
To test this I set up a simple Nuxt 3 installation with npx nuxi init nuxt-app, removed the demo content and replaced it with this:
pages/index.vue
<template>
<div>
<div id="home"><p>hello world</p></div>
<div class="menu">
<nuxt-link :to="{ path: '/', hash: '#ciao' }">
link
</nuxt-link>
</div>
<div style="height: 3000px">placeholder</div>
<div id="ciao"><p>ciao world</p></div>
<div class="menu">
<nuxt-link :to="{ path: '/', hash: '#home' }">
link
</nuxt-link>
</div>
<div style="height: 3000px">placeholder</div>
</div>
</template>
The problem is, that it is not working. The url in the browser is changed to localhost:3000/#ciao or localhost:3000/#home on click. But the view is not being changed.
Is there something else I need to set up in nuxt, to get anchor navigation to work?
As answered here: https://github.com/nuxt/framework/discussions/5561#discussioncomment-3007717
Using a regular a tag solves the issue
<a href="/#ciao">
go to ciao's hash
</a>
Otherwise, you can also use
<nuxt-link :to="{ hash: '#home' }" :external="true"> <!-- no need for a path if same page -->
go to home's hash
</nuxt-link>
The external prop (Nuxt3 only) is detailed here: https://v3.nuxtjs.org/api/components/nuxt-link#props
Quote from the documentation
Forces the link to be considered as external (true) or internal (false). This is helpful to handle edge-cases.

router-link VueJS can't link to an element in the same page

I'm trying to developp a sidebar of a documentation who it links to elements on th same page
<div class="mt-6">
<li class="relative">
<router-link class="menuItem-active-link" to="#users">
{{$t('navigation.users')}}
</router-link>
</li>
<li class="relative">
<a href="#advanced" class="menuItem-active-link" >
{{$t('navigation.advanced')}}
</a>
</li>
</div>
when I use the a tag I can navigate between each elements but I didn't know how styling the active link
And when I use router-link the URL change but the page stay on the current element, it does'nt go to the specified element on to attribute. And with router-link I can styling the active link easly:
.router-link-exact-active.menuItem-active-link{
background-color: cyan;
}
Have you any idea to solve this problem ?
This should work
<router-link :to="{ hash: '#users' }">{{ $t('navigation.users') }}</router-link>
Similar to this answer.

Can't get the params from components to the target route

I have a menu which is imported to the home and mine page. In home page I passed a data(user_id) to the menu.
<li>
<router-link to="/">
<i></i>
<div class="icon home"></div>
<span class="text">Home</span>
</router-link>
</li>
<li>
<router-link :to="{ path: '/mine', params: {id: user_id} }">
<i></i>
<div class="icon user"></div>
<span class="text">Mine</span>
</router-link>
</li>
On mine page, when I tried to display the params in console, it doesn't show.
but If the passing of data is from home to mine page it works.
I hope you can help me.
Thanks.
Structure
components
menu
views
home
mine
try this
<router-link :to="`/mine/${user_id}`">
to see information about your route try this command
console.log(this.$route)

using v-if to use different route-links in header cause route to wrong path

I am new to JavaScript Frameworks(although I used vanilla js or jquery(a little)) and I started with VueJS for my project.
I am writing a single page application that uses an restful-api as server.
I wanted that in header some links will appear if user is not logged-in(register, login) and disappear once logged in. And, of course, different set of links will appear.
a bit visualization :)
before login
HEADER => | Register(to='/register') Login(to='login')
after a successful login
HEADER => | Home(to='/') Profile(to='/profile') SomeOtherLink(to='/someOtherPath')
but sometimes, after login, although header is rendered correctly(I look in inspect and links were correct), It goes wrong pathes.
Such as first link before login was register and first link after login is home. When I clik home it goes to register. It is same for Profile and login. when I click profile it goes to /login. But third one works.
It seems somehow renders (not) wrong eventListener for links.
Here is my template.
...
<ul class="navbar-nav">
<template v-if="loggedIn">
<router-link :to="{name: 'Home'}"
tag="li"
class="nav-item"
active-class="active">
<a class="nav-link"> Home </a>
</router-link>
<router-link to="/profile"
tag="li"
class="nav-item"
active-class="active">
<a class="nav-link"> Profile </a>
</router-link>
<router-link :to="{name: 'SomeRoute'}"
tag="li"
class="nav-item"
active-class="active">
<a class="nav-link"> SomeLink </a>
</router-link>
</template>
<template v-else>
<router-link :to="{name: 'Register'}"
tag="li"
class="nav-item"
id="register-link"
active-class="active">
<a class="nav-link"> Kayıt Ol! </a>
</router-link>
<router-link
:to="{name: 'Login'}"
tag="li"
class="nav-item"
id="login-link"
active-class="active">
<a class="nav-link"> Giriş Yap </a>
</router-link>
</template>
</ul>
...
here loggedIn is computed property which is set true if user logs in, and false vice versa. It works correctly.
I tried using div instead of template tag but result was same.
How can I fix this?
Am I in wrong place? Or is it a bug?
I printed loggedIn and it was correct as I mentioned before.
Problem was not that though, Component rendered correctly. Problem was the click event listener I suppose.
Adding unique key to each route-link solved problem.
Most probably vue create an event-listener for each link, and once old links are destroyed and new links are rendered, it creates new listeners for new link but not remove old ones. Since there was no identity in links, it maps according to order.
Once old link is replaced with new one, it has two listener, one for old link that stayed in the same place, one for intended for the link. So it triggers one of them when clicked.
Actually it explains that why it works as intended first, after refresh works wrong, after another refresh again works correctly.
I'm not sure if it is a bug or not, but adding key is the only and true solution as it seems.

Vue, active router-link not updating after first change

I have a strange issue which I struggled with for a long time... I have a Sidebar with several router-links.
<template>
<div class="nav nav-pills main-nav" id="sidebar" role="tablist">
<router-link class="nav-link" to="/tasks">
Tasks
</router-link>
<router-link class="nav-link" to="/notes">
Notes
</router-link>
<router-link class="nav-link" to="/sounds">
Sounds
</router-link>
<div class="account">
<router-link class="nav-link" to="/profile">
Profile
</router-link>
<a class="nav-link" #click="logOut">
Log out
</a>
</div>
</div>
</template>
<script>
export default {
name: "sidebar",
methods: {
...
}
};
</script>
I have a strange issue with the behaviour of the latter menu. If I go to localhost:8080/notes, the notes button is active as expected. Then, if I click on any of the other link(let's say /tasks), it becomes active as expected. However, if I click on some link once again, /tasks remains active and the new page does not become active. That is, I will be able to navigate to other pages, but the /tasks router link will be active whatever I do. In other words, the "active" link is only updated once... I have no idea what the problem might be :/ Any suggestions are greatly appreciated!
In App.vue I import the sidebar
<div id="app">
<router-view name="header"></router-view>
<router-view name="sidebar"></router-view>
<main :class="{ 'remove-width': sidebarOpened }">
<fade-transition origin="center" mode="out-in" :duration="250">
<router-view />
</fade-transition>
</main>
</div>
My router.js start with
let router = new Router({
mode: "history",
linkExactActiveClass: "exact-active",
linkActiveClass: "active",
base: process.env.BASE_URL,
Pretty sure you shouldn't be having multiple router-views in your template. Can you remove those / replace them with the actual components and see if it fixes the issue? Something like this:
<div id="app">
<AppHeader />
<AppSidebar />
<main>
<fade-transition>
<router-view>
</fade-transition>
</main>
</div>
If it doesn't, you should post a bit more code of your components and router to help identify the issue.