Vue routing – '/' root url still active - vue.js

I have a simple routing:
export default new Router({
routes: [
{
path: '/',
name: 'Start',
component: Start
},
{
path: '/plan',
name: 'Plan',
component: Plan
},
{
path: '/cel',
name: 'Cel',
component: Cel
}
]
})
And I have also a simple menu:
<ul class="nav nav--top">
<li><router-link to="/">Start</router-link></li>
<li><router-link to="/plan">Plan</router-link></li>
<li><router-link to="/cel">Cel</router-link></li>
</ul>
It works fine, but I have a problem with active link class. A start url '/' has always class 'router-link-active' even I have active other url.
<ul class="nav nav--top">
<li>Start</li>
<li>Plan</li>
<li>Cel</li>
</ul>
How to fix it?

Related

How to display components of a child `router-view` that is nested within parent `router-view` in Vue JS?

I am trying to create a side menu (Dashboard's side menu with content) and I have to use multiple router-view.
First router-view is in App.vue that contains all the component.
<div id="app">
<router-view></router-view>
</div>
and the second router-view exists within above router-view as:
<div class="dashboard">
<Sidebar />
<div class="content">
<router-view name="content"></router-view>
</div>
</div>
According to below router/index.js code, if user visits / link, he will be redirected to dashboard page.
const routes = [
{
path: "",
name: "Dashboard",
component: dashboard,
},
{
path: "/messages",
name: "Messages",
components: {
content: Messages,
},
},
{
path: "/profile",
name: "Profile",
components: {
content: Profile,
},
},
{
path: "/settings",
name: "Settings",
components: {
content: Settings,
},
},
{
path: "/dashboard",
name: "Overview",
components: {
content: Overview,
},
},
];
and within above Sidebar component, there're links that upon clicking it shows the content of that link on right side (as in dashboard):
<div class="sidebar">
<div class="title">
Simple Sidebar
</div>
<div class="menu-items">
<router-link to="" active-class="active" tag="button" exact class="side-btn">
<div class="link-container">
Overview
</div>
</router-link>
<router-link to="/messages" active-class="active" tag="button" exact class="side-btn">
<div class="link-container">
Messages
</div>
</router-link>
// ....
</div>
</div>
for the second router-view I added a name as :
<router-view name="content"></router-view>
and then I identified it in router/index.js as:
{
path: "/messages",
name: "Messages",
components: {
content: Messages,
},
},
but it didn't work.
Can anyone help me debug and solve this issue, thank you in advance.
The nested route requires children route configs, which is missing from Dashboard's route config.
Move the route config of Messages into Dashboard's children array:
const routes = [
{
path: "",
name: "Dashboard",
component: dashboard,
children: [
{
path: "/messages",
name: "Messages",
components: {
content: Messages,
},
},
]
},
//...
]

Active class not being added when alias is used

I have below my routes
import Cart from './Cart.vue'
import ProductList from './ProductList.vue'
import ViewProduct from './ViewProduct.vue'
export const routes = [
{
path: '/',
name: 'index',
component: ProductList,
},
{
path: '/cart',
name: 'cart',
alias: '/shopping-cart',
component: Cart,
},
{
path: '/product/:product_id/view',
redirect: { name: 'view_product' },
},
{
path: '/product/:product_id',
props: true,
name: 'view_product',
component: ViewProduct,
},
{
path: '*',
component: {
template: '<h1>Page not found</h1>',
},
},
];
And as you can see my route or path /cart has an alias /shopping-cart.
Below are my router links as defined in App.vue with bootstrap#3 styles applied
<ul class="nav navbar-nav">
<router-link
:to="{
name: 'index'
}"
tag="li"
active-class="active"
exact>
<a>Products</a>
</router-link>
<router-link
:to="{
name: 'cart',
}"
tag="li"
active-class="active"
exact>
<a>Cart</a>
</router-link>
</ul>
When I navigate to /cart you can see that the active class is applied as in the screenshot below
but when I navigate to the alias /shopping-cart you can see below that the active class is not applied
What can be done so that when I navigate to the alias the active class for the link is also applied?
I have tried to change this
<router-link
:to="{
name: 'cart',
}"
tag="li"
active-class="active"
exact>
<a>Cart</a>
</router-link>
to this
<router-link
:to="{
name: 'cart',
alias: 'shopping-cart',
}"
tag="li"
active-class="active"
exact>
<a>Cart</a>
</router-link>
but to no avail.
Thank you.
the issue on this is still open in github. Reference: https://github.com/vuejs/vue-router/issues/419
you'll just have to rename your path to /shopping-cart and get rid of alias if you want active-class to be applied.

How to exhange a full route? Router-link exchanges only the last part of the route

I am new to vue and vue router and am using Vue router in history mode. The app contains a menu which is dynamically loaded
<router-link
tag="li"
class="link"
v-for="item in menu"
v-bind:key="item.id"
:to="item.slug"
:exact="item.slug === '/' ? true : false">{{ item.content }}
</router-link>
It works well as long as I stay in the parent routes like http://localhost:8080/posts As soon as I navigate a level deeper, e.g. to a post with the id 8 http://localhost:8080/posts/8 with a routerlink inside the Template
<router-link
tag="h2"
class="link"
:to="{ name: 'post', params: { id: post.id }}">
{{ post.title.rendered }}
</router-link>
it works in one way, but doesnt go back to the parent route when I click the main navigation links. Instead just adds the link of the main menu to the end of the route, e.g. instead of http://localhost:8080/posts
http://localhost:8080/posts/posts
The router
const router = new Router({
mode: 'history',
base: '',
routes: [
{ path: '/', name: 'home', component: HomePage },
{ path: '/posts', name: 'posts', component: PostsPage },
{ path: '/posts/:id', name: 'post', component: SinglePost },
{ path: '/projects', name: 'projects', component: ProjectsPage },
{ path: '/projects/:id', name: 'project', component: ProjectPage },
{ path: '/:page', name: 'page', component: SinglePage },
{ path: "*", redirect: '/' },
],
// etc..
});
I guess I am making a common mistake, but I can´t find a solution. Any help appreciated.
You can use absolute paths. Instead of
<router-link
tag="h2"
class="link"
:to="{ name: 'post', params: { id: post.id }}">
{{ post.title.rendered }}
</router-link>
use
<router-link
tag="h2"
class="link"
:to="{ name: '/post', params: { id: post.id }}">
{{ post.title.rendered }}
</router-link>
The change is /post vs post in router-link's :to attribute.
You could and probably should use nested routes and components for posts posts/:id, but this a little more work and you my not need it at the moment. More on nested routes here.

fixed sidebar with dynamic content in vue js

i'm trying to make my content component dynamic.(using vue-router)
this is my code:
<template>
<div class="row mb-3" id="customer-panel">
<Breadcrumb></Breadcrumb>
<CustomerSidebar></CustomerSidebar>
<div class="col-lg-9">
<PersonalInfo></PersonalInfo>
</div>
</div>
</template>
any thing is fixed in all pages except PersonalInfo component.
and this is my route:
{
path: '/customer',
component: Profile,
redirect: '/customer/profile',
children: [
{
path: 'profile',
name: 'profile',
component: Profile
},
{
path: 'order',
name: 'order',
component: Order
},
]
}
what should i do?
i don't want to repeat my code and copy & past in another component.
i just want when i go to order route, Order component loaded instead of PersonalInfo.
what is the best way?
https://router.vuejs.org/guide/essentials/nested-routes.html
You can acheive your desired result with <router-view></router-view>
Any nested routes / children of your parent route will be rendered here, on route change.
Component:
<template>
<div class="row mb-3" id="customer-panel">
<Breadcrumb></Breadcrumb>
<CustomerSidebar></CustomerSidebar>
<div class="col-lg-9">
<router-view></router-view>
</div>
</div>
</template>
Routes:
{
path: '/customer',
component: Customer,
children: [
{
path: 'profile',
name: 'profile',
component: Profile
},
{
path: 'order',
name: 'order',
component: Order
},
]
}
If I understand correctly, you could try using dynamic component selection using the is attribute:
<template>
<div class="row mb-3" id="customer-panel">
<Breadcrumb></Breadcrumb>
<CustomerSidebar></CustomerSidebar>
<div class="col-lg-9">
<component is="currentComponent"></component>
</div>
</div>
</template>
And associate currentComponent variable to the name of the component you want to use in the current route.
{
path: '/customer',
component: Profile,
redirect: '/customer/profile',
children: [
{
path: 'profile',
name: 'profile',
components: { default: Profile, currentComponent: MyComponent1 }
},
{
path: 'order',
name: 'order',
component: {default: Order, currentComponent: MyComponent2 }
},
]
}
See:
https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components
https://router.vuejs.org/guide/essentials/passing-props.html

Angular 5 Nested Routing

Here is my code
<ul>
<li> <a routerLink="/dashboard">Dashboard</a></li>
<li> <a routerLink="/price">Price</a> </li>
</ul>
and the routing part is
const routes: Routes = [
{ path: 'dashboard', component: DashboardComponent },
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{
path: 'price/:priceId',
component: PriceComponent,
children: [
{path: '', redirectTo:'kpi', pathMatch: 'full'},
{path: 'kpi', component: DashboardComponent},
{path: 'data', component: DashboardComponent},
]
}
];
here is the error that I got
ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'price'
Error: Cannot match any routes. URL Segment: 'price'
What is my mistake and how can I solve this. I want to do the nesting routing. on click on <li> <a routerLink="/price">Price</a> </li>. I want to open the http://localhost:4200/price/kpi default first child in nesting routing.