Wildcard routes with Vue.js - vue.js

I'm trying to match a Vue.js route like so:
{
path: '/#/reset*',
name: 'Confirm Reset Password',
meta: { title: `Confirm password reset` },
component: ConfirmResetPassword
},
to a URL that looks like this
mywebsite.com/#/reset-password
but it's not working- it just goes to the home page for some reason. Am I doing the wildcard wrong or is the '#' in a reserved namespace?
I also have these two routes:
{
path: '/',
name: 'Home',
component: Home
},
{
path: '*',
name: '404',
meta: { title: `Page not found` },
component: Error404
}
**Edit
I have history mode on and the URL is generated from a Django back-end

The /# shouldn't be a part of the path. Use like below:
{
path: '/reset*',
name: 'Confirm Reset Password',
meta: { title: `Confirm password reset` },
component: ConfirmResetPassword
},
The fact that you have /# in your URLs is because you don't have History mode on (which is not a problem, it is just a different way of using vue-router). So you declare your paths without /#.

If history mode is on I can't match against a URL provided pre-fixed with '#' - solution is to change the URL being generated on the back-end.

Related

Children components routing wont change to proper url

I am trying to set up router link for my settings page, whenever I click on Account, it directs me to localhost/account instead localhost/settings/account I've provided children for settings page, why is this happening?
Settings.vue
router-link(to="/")
button(class='hover:text-blue-500 focus:outline-none')
| Profile
router-link(:to="{name: 'Account'}")
button(class='hover:text-blue-500 focus:outline-none')
| Account
router-view
{
path: "/settings",
name: "Settings",
component: Settings,
children: [{
path: "",
name: "Profile",
component: Profile
},
{
path: "/account",
name: "Account",
component: Account
}
]
},
Remove the leading slash at account's path. Leading slash indicates it is a route from the root.
{
path: "/settings",
name: "Settings",
component: Settings,
children: [{
path: "",
name: "Profile",
component: Profile
},
{
path: "account", // now it works as intended
name: "Account",
component: Account
}
]
},

Vue 3 nested routes

Given the following route:
{
path: '/detail/:someId',
component: SomeDetailComponent,
name: 'some-detail',
children: [
{
path: 'dashboard',
component: DashboardComponent,
name: 'dashboard'
},
{
path: '',
redirect: { name: 'dashboard' }
},
{
path: 'other',
component: OtherComponent,
name: 'other'
}
]
},
Why does this work (the dashboard component is visible):
this.$router.push(`/detail/123/`);
But this doesn't:
this.$router.push({name: 'some-detail', params: { someId: 123 }});
In one case, the URL gets a trailing slash while in the other it doesn't. I've read somewhere in the docs that this is a breaking change coming from Vue2. See:
named-children-routes-with-an-empty-path-no-longer-appends-a-slash
So the real question here could be: how can I still have my working child navigations (with redirection) while still being able to navigate using the route name, instead of the route url part.

Vue Router issue with dynamic route

I am trying to make these routes:
{
path: '/',
name: 'home',
component: Home
},
{
path: '/:username',
name: 'login',
component: Login
},
{
path: '/dashboard',
name: 'dashboard',
component: Dashboard
}
But when I try to open /dashboard, I get Login page.
The order is important here. You can swap /dashboard and /:username position
[{
path: '/',
name: 'home',
component: Home
},
{
path: '/dashboard',
name: 'dashboard',
component: Dashboard
},
{
path: '/:username',
name: 'login',
component: Login
}]
That's normal. Router is matching the routes from first to last.
/dashboard totally matches /:username with username == 'dashboard'
You should place the login roote at the end of the array, but even better you'd prefix it to be safer (like /user/:username)

Links on the page with optional dynamic route is always without the param in vuejs

I have my routes as define below:
const router = new Router({
base: '/',
mode: 'history',
routes: [
{
path: '/',
redirect: `${DEFAULT_LOCALE}`,
},
{
path: '/:locale?',
component: AppTemplate,
children: [
{
path: 'home',
name: 'home',
component: () => import('#/views/Home.vue'),
meta: {
title: 'Home',
}
}
{
path: 'about',
name: 'about',
component: () => import('#/views/About.vue'),
meta: {
title: 'About',
},
},
{
path: 'contact',
name: 'contact',
component: () => import('#/views/Contact.vue'),
meta: {
title: 'Contact',
},
},
{
path: '*',
redirect: { path: '/' },
},
],
},
{
path: '*',
redirect: { path: '/' },
},
],
});
export default router;
I use :locale for app translation. It is optional because empty locale is for default language. My problem here is even if locale is present, all the links to other pages are without the locale, if that makes sense. For eg, example.com/about is in Italian and example.com/en/about is in English. But which ever URL it is, the links present on the page always points to contact or home page as example.com/contact and example.com/home. Is there a way to fix this? Or is there an easier way to use app translation from URL. I am using vue-i18n for the translation. Thanks
For such configuration I think you have to pass param to make it work:
<router-link :to="{name: 'contact', params: {locale: $route.params.locale} }">
https://jsfiddle.net/3gx4hak5/
Also maybe router-link append attribute will do the trick for you: https://router.vuejs.org/api/#append
Setting append prop always appends the relative path to the current path. For example, assuming we are navigating from /a to a relative link b, without append we will end up at /b, but with append we will end up at /a/b.
<router-link :to="{ path: 'relative/path'}" append></router-link>

vue-router default child route for tabs

I'm trying to have a homepage with tabs containing 2 lists, with 1 open by default.
I have the following route config, I've changed the names to simplify
let routes = [{
path: '/',
name: 'home',
component: require('./views/Home.vue'),
children: [{
path: 'list1',
name: 'home.list1',
component: require('./views/List1.vue')
}, {
path: 'list2',
name: 'home.list2',
component: require('./views/List2.vue')
}]
}
Inside ./views/Home.vue I have a <router-view></router-view> below 2 <router-link>s for each tab (child route).
When I visit the app route http://domain/ I would like to activate the list1 tab. The only way I can currently do this is if I visit http://domain/list1.
I have tried
children: [{
path: '',
name: 'home.list1'
and this initially works well, however if I visit http://domain/list2 both my tab links (router-links) have the active state.
JSFiddle which I can't get to run but helps for context
Is there a better solution to this?
Add one more child route with redirect (should be first)
children: [{
path: '',
redirect: 'list1', // default child path
},
...
]
For making a component(tab) appear default at visiting the parent route, you need to add a path as '' (empty string)
The following is a n example from the Vue Router docs
const router = new VueRouter({
routes: [
{
path: '/user/:id', component: User,
children: [
// UserHome will be rendered inside User's <router-view>
// when /user/:id is matched
{ path: '', component: UserHome },
// ...other sub routes
]
}
]
})
Don't use a '/', it will be considered as the root route.
You need to put the redirect on the parent, and it works on the first load.
Otherwise, it only works when I reload the page.
put redirect: 'home.list1' on the parent
put your child as path: ''
hope it works.
let routes = [{
path: '/',
name: 'home',
redirect: {name: 'home.list1'}, // Redirect to named route
// redirect '/list2' // Or redirect to path
component: require('./views/Home.vue'),
children: [{
path: '',
name: 'home.list1',
component: require('./views/List1.vue')
}, {
path: 'list2',
name: 'home.list2',
component: require('./views/List2.vue')
}]
}
I think what you want to do works if your home route isn't "/"
routes: [
{ path: '/home',
name: 'home',
component: require('./views/home.vue')
children: [
{ path: '/', name: 'list1', component: list1 },
{ path: 'list2', name: 'list2', component: list2},
],
}
]
This will load the home component and the list1 component inside of your initial . Then you can user router link to nav to list2:
<router-link :to="{ name: 'list2', params: { ...}}">
Or, maybe I don't understand the question.
Here is what works.
You have to use redirect: {name: 'home.list1'} (for the named route) property on your parent route 'home'.
Make sure you use the correct redirect property format either for named route (as above) or for path: redirect: '/list1'.
Here is the correct routes config which is only 1 line (the redirect one) different vs your config:
let routes = [{
path: '/',
name: 'home',
redirect: 'home.list1',
component: require('./views/Home.vue'),
children: [{
path: 'list1',
name: 'home.list1',
component: require('./views/List1.vue')
}, {
path: 'list2',
name: 'home.list2',
component: require('./views/List2.vue')
}]
}
Then every visit to / (your 'home' route) would be redirected to /list1.
Moreover, the router-link-active and router-link-exact-active will be correctly assigned on child link (both of them) and on parent link (only router-link-active).
This will also work for deeper nested non-child and child routes.
For more redirect & aliasig options see the official docs.