vue-router: navigate to nested state/route by name and params - vue.js

How can I navigate to a child state using $router.push?
My routes:
const routes = [
{
path: "/customers", name: 'Customers',
components: {content: CustomersMain},
props: {header: true, content: false},
children: [
{
path: '',
component: CustomerDetailsEmpty
},
{
path: ':id',
name: 'CustomerDetails',
component: CustomerDetails
}
]
}
];
How can I navigate to CustomerDetails with an id param set using
$router.push?

This did the trick:
this.$router.push({ name: `CustomerDetails`, params: {id} });

Related

Vue-router multiple active routes

Using vue-router, we have a nav menu which works, but we need an additional route to be recognized as "active" for the first nav item.
However the user starts their journey at "account/" (the root), which we show the same content for "/profile" as we don't intend on having actual homepage content to live in "account/".
Nav items:
account/profile ---> Needs class "router-link-active" for both "account/" and "account/profile" routes
account/plan
account/receipts
Routes:
const routes = [
{
path: '/account/',
component: ProfileBase,
children: [
{ path: '', name: 'AppHome', component: ProfileHome }
]
},
{
path: '/account/profile',
component: ProfileBase,
children: [
{ path: '', name: 'ProfileHome', component: ProfileHome },
]
},
{
path: '/account/plan',
component: PlanBase,
children: [
{ path: '', name: 'PlanHome', component: PlanHome },
{ path: 'cancel', name: 'PlanCancel', component: PlanCancel }
]
},
{
path: '/account/receipts',
component: ReceiptsBase,
children: [
{ path: '', name: 'ReceiptsList', component: ReceiptsList },
{ path: ':receiptID', name: 'ReceiptsDetail', component: ReceiptsDetail, props: true }
]
}
]

How to load a specific 'route' (vue-router) outside the main component (app.vue)?

I need to load a route outside the app.vue, I have a dashboard that works fine then I decided to implement a login which implied changing the app.vue, so after changing it I have the problem that my dashboard loads inside app.vue thus taking the styles of app.vue and completely deforming, so what now I need is to load outside of app.vue so it can work properly like it did before.
These are my routes:
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
mode: 'history', // to disappear the # in URL's
base: process.env.BASE_URL,
routes: [
//HOME
{
name: 'Home',
path: '/',
component: () => import('#/components/Home.vue'),
},
//LOGIN
{
name: 'Login',
path: '/login',
//component: () => import('#/views/login/Login'),
component: () => import('#/components/Login.vue'),
},
//REGISTER
{
name: 'Register',
path: '/register',
component: () => import('#/components/Register.vue'),
},
//DASHBOARD
{
//name: 'Dashboard',
path: '/dash',
name: 'dashboardd',
component: () => import('#/views/dashboard/Index'),
children: [
//CLIENTS
{
name: 'Clients',
path: '/Clients',
component:()=> import('#/views/clientss/Clientss')
},
//SALES
{
name: 'Sales',
path: '/sales',
component:()=> import('#/views/sales/Sales')
},
//NUEVA VENTA
{
name: 'Sales',
path: '/new-sale',
component:()=> import('#/views/sales/NewSale')
},
//productos
{
name: 'Productos',
path: '/products',
component:()=> import('#/views/articulos/Products')
},
//listar articulos
{
name: 'ListarArticulos',
path: '/articulos',
component:()=> import('#/views/articulos/ListarArticulos')
},
//crear articulo
{
name: 'CrearArticulo',
path: '/articulos/crear',
component:()=> import('#/views/articulos/CrearArticulo')
},
//editar articulo
{
name: 'EditarArticulo',
path: '/articulos/editar/:id',
component:()=> import('#/views/articulos/EditarArticulo')
},
// Dashboard
{
name: 'Dashboard',
path: '/dash',
component: () => import('#/views/dashboard/Dashboard'),
},
{
name: 'PROVEEDORES',
path: '/providers',
component: () => import('#/views/providers/Provider'),
},
{
name: 'USUARIOS',
path: '/users',
component: () => import('#/views/users/User'),
},
{
name: 'REPORTES',
path: '/reports',
component: () => import('#/views/reports/Report'),
},
// Pages
{
name: 'User Profile',
path: 'pages/user',
component: () => import('#/views/dashboard/pages/UserProfile'),
},
{
name: 'Notifications',
path: 'components/notifications',
component: () => import('#/views/dashboard/component/Notifications'),
},
{
name: 'Icons',
path: 'components/icons',
component: () => import('#/views/dashboard/component/Icons'),
},
// Maps
{
name: 'Google Maps',
path: 'maps/google-maps',
component: () => import('#/views/dashboard/maps/GoogleMaps'),
},
],
},
],
})
And I need to load the route named 'Dashboard' outside the App.vue. Because of my dashboard has his own styles and work properly when it is the only app running :
You can simply access the router from all components that are part of your Vue by using this.$router.
In Vue 2, you would need to call this.$router.push({name:'Dashboard'}) to instantly navigate to the route named 'Dashboard'.

Vue named views with lazy loading

I am trying to create my routes, but I want them to all use the default router-view in my app.
Looking at the documentation:
https://router.vuejs.org/guide/essentials/named-views.html
I should be able to target views by doing something like this:
const routes = [
{
path: "/",
name: "home",
component: {
default: Home
},
},
]
I want to do this with a child, so I did this:
{
path: "/categories",
name: "categories",
meta: {
title: "Categories",
},
component: Categories,
children: [
{
path: ":slug",
name: "product-list",
meta: {
title: "Categories",
},
component: { default: ProductList },
],
},
],
},
I get no compile errors, but when navigating to /categories/televisions it only shows the Categories component, not the ProductList.
So my first question is, can children target app level router-view?
I also tried to add a new router-view like this:
<router-view />
<router-view name="root" />
and then updated my routes to this:
{
path: "/categories",
name: "categories",
meta: {
title: "Categories",
},
component: Categories,
children: [
{
path: ":slug",
name: "product-list",
meta: {
title: "Categories",
},
component: { root: ProductList },
},
],
},
But this didn't work either.
If it is possible to do this, then my next question, which is where I am heading.
Can I use lazy loaded components and target named/default router-views?
For example, I have this function:
const lazyLoad = (name) => {
return () => import(`../views/${name}/${name}.component.vue`);
};
Which I call from my routes like this:
{
path: "/categories",
name: "categories",
meta: {
title: "Categories",
},
component: lazyLoad("categories"),
children: [
{
path: ":slug",
name: "product-list",
meta: {
title: "Categories",
},
component: lazyLoad("product-list"),
},
],
},
Can I do it like this?
{
path: "/categories",
name: "categories",
meta: {
title: "Categories",
},
component: lazyLoad("categories"),
children: [
{
path: ":slug",
name: "product-list",
meta: {
title: "Categories",
},
component: { default: lazyLoad("product-list") },
},
],
},
and target the root router-view?

Vue-router - using two different paths, children don't load from second path

children in route, name: matchDayRegistrationResult don't get loaded, when I move them to name: matchDays they load fine. But I need a different top level component, HomepageLayoutRatio5050 -> HomepageLayoutRatio2575
I could not find a working example in the Vue docs
const router = new VueRouter({
mode: 'history',
routes:
[
{
path: '/:lang',
name: 'matchDays',
component: HomepageLayoutRatio5050,
children: [
{
path: '/:lang',
components: {
descriptionBlock: MatchDaysDescription,
mainBlock: MatchDaysTable,
notesBlock: MatchDaysNotes
}
},{
path: '/:lang/matchday/registration/:id',
name: 'matchDayRegistration',
components: {
descriptionBlock: RegistrationFormDescription,
mainBlock: RegistrationForm
}
}]
},
{
path: '/:lang/matchday/registration/result/:id',
name: 'matchDayRegistrationResult',
component: HomepageLayoutRatio2575,
children: [
{
path: '/:lang/matchday/registration/result/:id',
components: {
descriptionBlock: RegistrationResultDescription,
mainBlock: RegistrationResultDetails,
notesBlock: RegistrationResultNotes
}
}]
}
]
});
HomepageLayoutRatio2575 does load,
but children: descriptionBlock: RegistrationResultDescription
mainBlock: RegistrationResultDetails notesBlock:
RegistrationResultNotes Don't.
Found THE solution, as the localisation part, /:lang was the culprit, blocking the second route (...logic) I reordered the routing schema.
To the benefit of people, having hard times, looking for complex vue router-view solutions, localisation aware, here's the solution :-)
const router = new VueRouter({
mode: 'history',
routes:
[
{
path: '/:lang',
component: HomeSweetHome,
children: [{
path: '/:lang',
name: 'matchDays',
components: {
homepageSidebarLayoutRatio: HomepageSidebarLayoutRatio5050,
homepageMainLayoutRatio: HomepageMainLayoutRatio5050,
footer: FooterGray
},
children: [
{
path: '/:lang',
components: {
descriptionBlock: MatchDaysDescription,
mainBlock: MatchDaysTable,
notesBlock: MatchDaysNotes
}
},{
path: '/:lang/matchday/registration/:id',
name: 'matchDayRegistration',
components: {
descriptionBlock: RegistrationFormDescription,
mainBlock: RegistrationForm
}
}
]
},{
path: '/:lang/matchday/registration/result/:id',
components: {
homepageSidebarLayoutRatio: HomepageSidebarLayoutRatio2575,
homepageMainLayoutRatio: HomepageMainLayoutRatio2575,
footerNotesBlock: RegistrationResultFooterNotes,
footer: FooterBlack,
},
children:[{
path: '/:lang/matchday/registration/result/:id',
name: 'matchDayRegistrationResult',
components: {
descriptionBlock: RegistrationResultDescription,
mainBlock: RegistrationResultDetails
}
}]
}]
}
]
});

How to go to a child route by route name?

I know we can go to a route by its name using $router.push({ name: 'route-name' }).
What I want to know is how to do that with a child route name.
This is my route structure:
export default [
{
path: '/',
name: 'home',
component: () => import('#/views/Home.vue'),
childs: [
{
name: 'home.about',
path: '/about',
component: import('#/views/Home/About.vue')
}
]
}
]
But my console says [vue-router] Route with name 'home.about' does not exist for $router.push({ name: 'home.about' }).
What I'm missing?
Obs: The idea is to not route to the child using a hard route path.
const router = new VueRouter({
routes: [{
path: '/foo',
name: 'foo',
component: Foo,
children: [
{
path: 'fooChild1',
name: 'fooChild1',
component: FooChildComponent
},
{
path: 'fooChild2',
name: 'fooChild2',
component: FooChildComponent
}
]
}, {
path: '/bar',
component: Bar
}]
})
Now if you wish to navigate to fooChild1 then use $router.push({ name: 'fooChild1' }) or if you wish to navigate to fooChild2 then use $router.push({ name: 'fooChild2' })
You have a typo.
It should be children and not childs.
export default [
{
path: '/',
name: 'home',
component: () => import('#/views/Home.vue'),
children: [
{
name: 'home.about',
path: '/about',
component: import('#/views/Home/About.vue')
}
]
}
]