Vue Router issue with dynamic route - vue.js

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)

Related

Vue Router Sidebar navigation item link changes while visiting inner pages

I have a SPA App in Vue JS, I have a side navigation bar which I want to stay visible for all pages. I have following links setup in side navigation bar
{
name: 'Overview',
icon: 'ti-dashboard',
path: 'overview',
},
{
name: 'Areas',
icon: 'ti-map-alt',
path: 'areas',
},
{
name: 'Assignments',
icon: 'ti-check-box',
path: 'assignments',
},
{
name: 'Records',
icon: 'ti-view-list-alt',
id: 'third-party',
children: [
{
name: 'Vaccination',
path: 'vaccination',
},
{
name: 'Out-of-Area Vaccinations',
path: 'vaccination/outer',
},
{
name: 'Surveys',
path: 'survey',
},
{
name: 'Archived',
path: 'archived',
},
],
}
...
Following is my router setup
const routes = [
{
path: '/',
component: App,
},
{
path: '/login',
component: require('../../../assets/js/components/Template/AppLogin.vue'),
},
{
path: '/platform/projects',
component: require('../../../assets/js/components/Template/Projects.vue'),
meta: {requiresAuth: true},
},
{
path: '/project/:projectId',
component: require('../../../assets/js/components/Template/UIComponents/SidebarPlugin/SideBarNew.vue'),
props: route => ({projectId: route.params.projectId}),
children: [
{
path: 'overview',
component: require('../../../assets/js/components/Template/mvdProjectOverview.vue'),
},
{
path: 'areas',
component: require('../../../assets/js/components/Template/AddVaccinationArea.vue'),
},
{
path: 'assignments',
component: require('../../../assets/js/components/Template/AssignAreaUsers.vue'),
},
{
path: 'vaccination',
component: require('../../../assets/js/components/Template/VaccinationRecord.vue'),
},
{
path: 'vaccination/outer',
name: 'projectOuterVaccinations',
component: require('../../../assets/js/components/Template/OuterVaccinations.vue'),
},
{
path: 'archived',
name: 'projectOuterVaccinations',
component: require('../../../assets/js/components/Template/ArchivedRecords.vue'),
},
{
path: 'survey',
component: require('../../../assets/js/components/Template/Surveys.vue'),
},
...
const router = new VueRouter({
routes,
mode: 'history'
})
When I visit vaccination/outer All of my side bar navigation links are appended with vaccination
Attaching images for more clarity
Here the URL is good and should stay like this only
When I navigate to vaccination/outer
The issue: Now all the links gets vaccination in between
I have a very basic knowledge of VUE ROUTER and ROUTER LINK. A help or guidance would be great. Thanks in advance.
I am pretty sure you are using paths from presented array as: <router-link to="LINK">some label</router-link>. However, as your path values are not starting with / - vue router will add value of to property to the current URL instead of replace it.
Let's imagine I am on /a/b/c URL.
When I click on <router-link to="dogs">Dogs</router-link> - I will be redirected to the /a/b/c/dogs.
When I click on <router-link to="/dogs">Dogs</router-link> - I will be redirected to the /dogs.
All you need to do is, start paths with the slash. So instead of path: vaccination/outer use path: /vaccination/outer and it will work as you want to.

Vue.js weird behavior of router after refreshing page

I have a problem with dynamic routes in my vue.js application. When i enter page from a routerLink click everything works as it should. But when i refresh that page or i enter there from normal href the page acts weird. It looks then like it's not loading static assets like styles which were reset in public/style.css. Also component lifecycle methods are not firing up (created(), mounted() etc.).
Reproduction here:
1. Enter https://blooming-dusk-66903.herokuapp.com/profiles
2. Enter on one of profiles
3. Refresh when on https://blooming-dusk-66903.herokuapp.com/profiles/*******
here is my router file
Vue.use(Router);
export default new Router({
mode: "history",
routes: [
{
path: "/landing",
name: "Landing",
component: Landing
},
{
path: "/register",
name: "RegisterForm",
component: RegisterForm
},
{
path: "/",
name: "Dashboard",
component: Dashboard
},
{
path: "/profile",
name: "UserProfile",
component: UserProfile
},
{
path: "/profile/:id",
name: "Profile",
component: Profile
},
{
path: "/edit-profile",
name: "EditProfile",
component: EditProfile
},
{
path: "/friends",
name: "Friends",
component: Friends
},
{
path: "/profiles",
name: "Profiles",
component: Profiles
},
{
path: "/friend-requests",
name: "FriendRequests",
component: FriendRequests
},
{
path: "/post/:id",
name: "Post",
component: Post
},
{
path: "/chat/:handle",
name: "ChatWith",
component: ChatWith
}
]
});

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 components with the same route

I have several components. This is the routes file
routes: [
{ path: '/members/logout', name: 'logout', component: Logout, meta: { pageTitle: 'Logout' } },
{ path: '/members/contact', name: 'contact', component: Contact, meta: {pageTitle: 'Contact'} },
{ path: '/', name: 'offline', component: LoggedOut, meta: {pageTitle: 'Logged Out'}, children: [
{ path: 'members/login', name: 'login' component: Authenticate, meta: {pageTitle: 'Authenticate'} },
{ path: 'members/signup', name: 'signup', component: Signup, meta: {pageTitle: 'Signup'} },
{ path: 'members/confirm', name: 'not-confirmed', component: NotConfirmed, meta: {pageTitle: 'NotConfirmed'} },
{ path: 'connect/callback', name: 'connect', component: Connect, meta: {pageTitle: 'Connect'} }
]}
]
On page load I'm checking to see if the user has logged or not before. If it has, I show the Login component, if not - the Signup. Everything works, but I want something else.
When I go to domain.com initially I don't want the link to switch to /members/login or /members/signup, only if the user presses a link inside the website. I want the route to remain domain.com and show the appropriate component between login or signup.
I tried with alias but that works only for one

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.