Active class not being added when alias is used - vue.js

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.

Related

Prevent transition from child component to parent component with vue

I'm doing Router with Vue Js, but the thing I want to do is:
Sample:
domain.com/post/1
while the page is open,
again
I don't want it to switch to /post via the menu
Is there a way to prevent this
import Home from "./website/Home.vue";
import Post from "./website/Post.vue";
import PostDetail from "./website/PostDetail.vue";
export default [
{
path: '',
component: Home,
name: 'home',
},
{
path: 'post',
component: Post,
name: 'post',
children: [
{
path: ':id',
name: 'PostDetail',
component: PostDetail,
props: true
}
]
},
]
app.vue
<div>
<router-link to="/">Home</router-link>
<router-link to="/post">Post</router-link>
</div>
<router-view/>
post.vue
<div>
<router-link :to="{name: 'PostDetail', params: {id: 1}}"/>
</div>
<div class="child">
<router-view/>
</div>
postdetail.vue
<div>
Child Component
</div>

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,
},
},
]
},
//...
]

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.

Vuejs - router children

I'm trying to figure out how child routes in VueJS work. I would think that if I had a news overview with links to each news item, I could then use a child route to view the news item, but it doesn't works as I expects.
Is it me that is doing it wrong or?
const router = new VueRouter({
routes: [
{
path: '/news',
name: 'news',
component: News,
children: [
{
path: ':id',
name: 'newsitem',
component: Newsitem
}
]
}
]
});
I have created a jsfiddle to show how I would expect it to work.
If I uncomment the router in the javascript, then it works fine, but not with children.
Like Moersing.Lin said you forgot to put a <router-view> in your News Component.
Here is an working example of your fiddle:
const News = {
template: `<div>
<h1>News</h1>
<br><br>
<router-view></router-view>
</div>
`
}
const Newsitem = {
template: "<h2>News {{this.$route.params.id}}</h2>"
}
const router = new VueRouter({
routes: [{
path: '/news',
name: 'news',
component: News,
children: [{
path: ':id',
name: 'newsitem',
component: Newsitem,
}]
}]
});
new Vue({
el: '#app',
router,
}).mount('#app');
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<ul>
<li>
<router-link :to="{ name: 'news'}">News list</router-link>
</li>
<li>
<router-link :to="{ name: 'newsitem', params: { id: 'item-1' }}">Item 1</router-link>
</li>
<li>
<router-link :to="{ name: 'newsitem', params: { id: 'item-2' }}">Item 2</router-link>
</li>
</ul>
<router-view></router-view>
</div>
I got it, A Vue Router is required <router-view></router-view>,but in your code, The root component is there, but you forgot the parent,it needs a <router-view></router-view> too.
https://jsfiddle.net/v28yw3g5/
const News = {
template: `<div>
<h1>News</h1>
<br><br>
<router-view></router-view>
</div>
`
}
const Newsitem = {
template: "<h2>News {{this.$route.params.id}}</h2>"
}
const router = new VueRouter({
routes: [{
path: '/news',
name: 'news',
component: News,
children: [{
path: ':id',
name: 'newsitem',
component: Newsitem,
}]
}]
});
new Vue({
el: '#app',
router,
}).mount('#app');
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<ul>
<li>
<router-link :to="{ name: 'news'}">News list</router-link>
</li>
<li>
<router-link :to="{ name: 'newsitem', params: { id: 'item-1' }}">Item 1</router-link>
</li>
<li>
<router-link :to="{ name: 'newsitem', params: { id: 'item-2' }}">Item 2</router-link>
</li>
</ul>
<router-view></router-view>
</div>

Vue routing – '/' root url still active

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?