Vue.js Multiple independent routes - vuejs2

Description:
I am building a electron based Vue.js app with a settings icon that is always visible. Once the user clicks this icon, a settings modal will pop-up. This popup contains its own navigation / router-links.
Question:
Is it possible to only navigate a specific named router-view without actually navigating the main router-view
E.g. in Angular this would be done using the outlet prop:
path: 'settings-general',
outlet: 'settingsOutlet',
component: SettingsGeneralComponent
But in Vue all I could find was something like the snippet below, which navigates the main router-view to nothing
path: '/settings-general',
name: 'settings-general',
components: {
// default: This should just keep the current loaded component
settingsOutlet: require('#/components/SettingsGeneral').default
}
Below is my current Router config:
export default new Router({
routes: [
{
path: '/',
name: 'login-page',
component: require('#/components/LoginPage').default
},
{
path: '/home',
name: 'home-page',
component: require('#/components/HomePage').default
},
{
path: '/settings',
name: 'settings-page',
components: {
settingsRouter: require('#/components/SettingsPage').default
}
},
{
path: '*',
redirect: '/'
}
]
})

Related

Vue Router in Vue.js 3.0 problem with redirecting named page to other named page

this is propably basic question to ask but i have a problem with router settings. I have managed to build a nice, clean Views inside CMS system i am working on and my router settings looks like
const routes = [{
path: "/cms/dashboard/",
redirect: "/cms/dashboard/summary/"
}, {
path: "/cms",
name: "CMS",
component: CMS,
children: [{
id: ":id",
path: ":viewSlug",
name: "cmsView",
props: true,
component: () => import( /*webpackChunkName: "dashboard" */ "../views/CMS/CmsView.vue"),
children: [{
id: ":id",
path: ":childSlug",
name: "nestedRoute",
props: true,
component: () => import( /*webpackChunkName: "dashboard" */ "../views/CMS/NestedView.vue"),
children: [{
id: ":id",
path: ":secondChildSlug",
name: "nestedSecond",
props: true,
component: () => import( /*webpackChunkName: "dashboard" */ "../views/CMS/SecondNestedView.vue"),
}]
}]
}],
}];
so as you can see i am basically using only named routes which is neat because i can design all the pages i want in CMS to be just .json files that are included in store. The problem is redirecting seems not to work properly. The code:
{
path: "/cms/dashboard/",
redirect: "/cms/dashboard/summary/"
}
Works only when i refresh the page - so when I refresh a page when i am under /cms/dashboard - redirect works just fine, but when i go to "/cms/dashboard" via navigation - nothing happens. That's a little bit frustrating because i just want to always show child component as well as main component in every view.

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
}
]
});

Vue router not following children paths

I'm having problems to make my http://localhost:8080/myapps/config route load. If I use http://localhost:8080/myapps everything works ok and I get a list of my apps. But when I want to access an app config through http://localhost:8080/myapps/config it loads the content of /myapps again. However, the url in my browser shows the correct path /myapps/config.
I have been checking the routher for some hours but everything seems to be ok. Could anybody shed some light?
My router file:
import Vue from 'vue'
import Router from 'vue-router'
const MyApps = () => import('../views/app/subviews/MyApps');
const AppKeyValue = () => import('../views/app/subviews/AppKeyValue');
import MainView from '../views/app/MainView'
Vue.use(Router)
export default new Router({
mode: 'history',
routes:
[
{
path: '/',
component: MainView,
redirect: 'myapps',
children:
[
{
path: 'myapps',
component: MyApps,
meta:
{
requiresAuth: true,
breadcrumb: 'My Apps'
},
children:
[
{
path: 'config',
component: AppKeyValue,
meta:
{
requiresAuth: true,
breadcrumb: 'App configuration'
}
},
]
},
]
},
]
})
Everything works ok if I don't use child routes:
export default new Router({
mode: 'history',
routes:
[
{
path: '/',
component: MainView,
redirect: 'myapps',
children:
[
{
path: 'myapps',
component: MyApps,
meta:
{
requiresAuth: true,
title: 'message.ecommerce',
breadcrumb: 'My Apps'
},
},
{
path: 'myapps/config',
component: AppKeyValue,
meta:
{
requiresAuth: true,
title: 'message.ecommerce',
breadcrumb: 'App configuration'
}
}
]
}
]}
You didn't post your *.vue components, but I assume you're missing <router-view> in the second level component.
Example:
MainView is mapped to / and has 1 children route (/myapps). You're probably using <router-view> in your MainView.
MyApps is mapped to myapps as a children of the /-route and has 1 children route (/config).
Add a <router-view to your MyApps.vue to let it display its children (which is just /config in your case).
Similarly, a rendered component can also contain its own, nested <router-view>.
https://router.vuejs.org/guide/essentials/nested-routes.html#nested-routes
BTW: That's also why your second router config is working: The main route has two children (/myapps and /myapps/config), which both get displayed by the MainView's <router-view>.
Here is a working example from the documentation:
https://jsfiddle.net/nazgul_mamasheva/zrcLe9z7/1/

VueJS - Go directly to children route

I've made a dashboard with vuejs.
My problem is that i want to go directly to a route "dashboard/my-profile".
This route is a children of another :
{
path: '/dashboard',
name: 'dashboard',
components: { default:Dashboard },
children: [
{
path: 'my-profile',
name: 'show_profile',
components: {
subview: Profile
}
}
]
}
When i try to directly go to 'dashboard/my-profile' it load good but immediately redirect to 'dashboard' his parent
Do you have any idea how can i do that ?
It seems you have not defined router-view for the Profile:
<router-view></router-view><!-- Default: Dashboard -->
<router-view name="subview"></router-view><!-- Profile -->

Vue.js nested routing with default child

I have an issue with a default children route in Vue.js 2.
When I visit localhost/listings initially, it correctly loads index.vue and map.vue as a child.
When I navigate using router-link to localhost/listings/1, and then using router-link back to localhost/listings, then it still loads the show.vue template. This shouldn't happen?
I have no navigation guards or anything that should interfere. Is there anyway to correct this?
My routes:
window.router = new VueRouter({
routes: [
...
{
path: '/listings',
name: 'listing.index',
component: require('./components/listing/index.vue'),
children: [
{
path: '',
component: require('./components/listing/map.vue')
},
{
path: ':id',
name: 'listing.show',
component: require('./components/listing/show.vue')
}
]
},
...
]
});
The "father" router should not be named if you want a default child route, so instead using :to="{name: 'listing.index'}", use the name of the default child route (e.g :to="{name: 'listing.map'}").
The code should look like this:
window.router = new VueRouter({
routes: [
...
{
path: '/listings',
component: require('./components/listing/index.vue'),
children: [
{
path: '',
name: 'listing.map'
component: require('./components/listing/map.vue')
},
{
path: ':id',
name: 'listing.show',
component: require('./components/listing/show.vue')
}
]
},
...
]
});
Maybe try re-arranging the children, routes are fired in the order they match from top-to-bottom, so this should hopefully fix it:
window.router = new VueRouter({
routes: [
...
{
path: '/listings',
name: 'listing.index',
component: require('./components/listing/index.vue'),
children: [
{
path: ':id',
name: 'listing.show',
component: require('./components/listing/show.vue')
}
{
path: '',
component: require('./components/listing/map.vue')
},
]
},
...
]
});
Just for a bit of clarification, your path: '' essentially serves as a "catch all", which is likely why when it's at the top it's being found immediately and so the router never propagates any further down to the :id route.
In Vue 2.6.11 you can automatically redirect to a child route if parent route is hit:
const routes = [
{
name: 'parent',
path: '/',
component: Parent,
children: [
{
name: 'parent.child',
path: 'child',
component: Child,
}
],
/**
* #type {{name: string} | string} Target component to redirect to
*/
redirect: {
name: 'parent.child'
}
}
];
When you are using named routes and you want to load the component with your child inside, you have to use the name route for the child.
In your Navigation menu links, if you use name route for the parent, the child will not load automatically, even if the child path is nothing.
Let's say for example we have a User route, and we want to show list of users inside the component by default so whenever we go to '/user' path we want to load a list of users as a child in there:
routes: [
{
path: '/user',
name: 'User',
component: User,
children: [
{path: '', name: 'UserList', component: UserList}, // <== child path is = '';
]
}
]
If you think about the code, you might assume if you go to route with name 'User' you might get UserList in there as well, because the path for parent and children both are same. but it's not and you have to choose 'UserList' for the name.
Why this is happening?
Because Vuejs loads the exact component you are referring to, not the url.
you can actually test this, instead of using named route in your links, you can just refer the url, this time vuejs will load the parent and child together with no problem, but when you use named route, it doesn't look at the url and loads the component you are referring to.