Optional sub-path in Vue Router - vue.js

Given the following route to the UserIndexPage in vue-router:
{
path: '/user/:userId/:orderId?',
name: 'userIndex',
props: true,
component: UserIndexPage
}
I'm aware that :orderId? makes this parameter optional. Now, I'd like to preprend a path to the orderId, that is, both of the following paths should match and route to the same component:
/user/:userId
/user/:userId/order/:orderId?
Is vue-router capable for this?

Related

migration default child route from vue router v2 to vue router v3

Migration guide says:
Named children routes with an empty path no longer appends a slash
his has an important side effect about children redirect records like these:
const routes = [
{
path: '/parent',
component: Parent,
children: [
// this would now redirect to `/home` instead of `/parent/home`
{ path: '', redirect: 'home' },
{ path: 'home', component: Home },
],
},
]
Notice:
// this would now redirect to /home instead of /parent/home
But I would like to redirect to /parent/home instead of /home
Docs:
https://router.vuejs.org/guide/migration/#named-children-routes-with-an-empty-path-no-longer-appends-a-slash
So how can one achieve original behaviour before this change with new router? I would like to have relative redirect to a child.
Vue2 playground it works as expected.
Vue3 playground broken by change.

Why does Vue router require an empty path child route to be named in order to render?

I have a route setup where there's a parent with child routes, like this:
{
//name: 'ProductComments',
path: 'comments',
children: [
{
name: 'ProductComments',
path: '',
component: ProductComments
},
{
name: 'EditProductComment',
path: ':commentId/edit',
component: EditProductComment
}
]
}
With the above configuration, Vue Router will render my ProductComments component if I visit /comments. However, if I comment the name out and uncomment it on the parent, it won't render the ProductComments component and will give me the warning:
The route named "ProductComments" has a child without a name and an empty path. Using that name won't render the empty path child so you probably want to move the name to the child instead. If this is intentional, add a name to the child route to remove the warning.
But why is this? The child is always a more "specific" route, so why does giving it a name magically cause it to render, whereas giving the name to the parent stops it?
I think this is one of those things that was decided by the Vue team and only they can really answer why. I was curious about it though and found this
github thread talking about the exact same thing. Doesn't seem like a satisfactory answer was ever found but the comment I specifically linked contains a workaround which is just adding a redirect:
{
path: '/user/:id',
name: 'user',
/* Explicitly tell the router to redirect to default children */
redirect: '/user/:id/',
component: User,
children: [
{
path: '',
component: UserProfile
},
{
path: 'posts',
component: UserPosts
}
]
}
Set everything in the parent; it makes more semantic sense too.
My parent/child routes function like this. I haven't had any problems with this (so far?).
{
name: 'ProductComments',
path: 'comments',
component: ProductComments
children: [
{
name: 'EditProductComment',
path: ':commentId/edit',
component: EditProductComment
}
]
}

router-link-active not applied to matching routes [duplicate]

This question already has an answer here:
Vue 3 router - router-link-active not working
(1 answer)
Closed 6 months ago.
I am currently in my Vue learning journey. I have come across a situation where I need to show my link as active for matching route too. For example: I have route /programs which shows Program link as active without any issues but I also want /programs/view to set Program link as active as well. How do I do it in Vue Router?
These are my route definitions in router.js file
const routes = [
{ path: '/', component: Main, name: 'main', redirect: '/dashboard', children:
[
{ path: '/dashboard', component: Dashboard, name: 'dashboard' },
{ path: '/programs', component: Programs, name: 'programs' },
{ path: '/programs/view', component: ViewProgram, name: 'view_program'},
...OTHER ROUTES
]
},
{ path: '/login', component: Login, name: 'login', meta: {noAuth: true} },
{ path: '/:pathMatch(.*)*', redirect: '/dashboard'}
];
I searched and found that router-link-active class should be automatically applied to Program link when the route starts with /programs, but it is not working in my case.
EDIT
I have found a workaround by manually matching route and appending active class to the router link. But I still expect an easier way to do this.
In my Program link:
<router-link to="/programs" :class="{'router-link-active': $route.fullPath.match(/\b\programs/) }">
<span>Programs</span>
</router-link>
I am using regex to match path pattern. So, every route that contains programs will get active class here.
dont u gotta do that in the component and not in the router?
take what i say with a grain of salt im

Vue routing - how to use clean URLs with /:slug for multiple components

I'm looking for a solution to get the current situation:
Pages - domain.com/page-name (example: /contact)
Categories - domain.com/category-name (example: /blog)
With Vue I'm unable to create this with the slug as a prop.
{
path: '/:slug',
name: 'Page',
props: true,
component: () => import('../views/Page.vue')
},
{
path: '/:slug', // /category/:slug will work but I would like /:slug als path
name: 'Category',
props: true,
component: () => import('../views/Category.vue')
}
I know that a different path wil fix this, for example: '/category/:slug' but I'm looking for a way to create clean URLs without a prefix. Is this possible?

How to use * (asterisk) in NuxtJs route?

In a normal Vue (not Nuxt) project generated by vue-cli, using * in vue-router like this works:
export default new Router({
routes: [
{
path: "/about",
name: "about",
component: About,
children: [
{
path: "*",
component: About
}
]
}
]
});
All these routes works:
/about
/about/123
/about/123/abc/123/abc
Is there a way to do this in NuxtJs ? In Nuxt, routes are generated automatically from the files in pages folder. but * is an invalid character for file/folder name.
You use _ to denote that it's a wildcard, like:
pages/about/_.vue
Will resolve /about/*, which is what I believe you're looking for
And if you want the dynamic directory structure:
pages/about/_/abc/_/abc.vue
Would resolve for about/123/abc/123/abc (but it doesn't make much sense)