Load Vue's parent component and all nested routes lazily - lazy-loading

I have an issue with lazy loading of my nested routes!
this is my parent route:
import ChildRoutes from "app/modules/child.route”;
routes: [
{
path: '/child',
component: resolve => require(['app/modules/root'], resolve),
children: ChildRoutes
}
]
and my child.route.js is
import ChildHome from …
import ChildContact from …
export default [
{
path: '',
name: 'childHome',
component: ChildHome
},
{
path: 'about',
name: 'childAbout',
// doesn’t work
component: resolve => require(['./components/about.vue'], resolve)
},
{
path: 'contact',
name: 'childContact',
// this one doesn’t work as well
component: ChildContact
},
...
]
Of course the first sub-rout (childHome) works automatically, but after that I just get blank pages with no component rendered!
If I load neither parent nor children lazily, everything will be fine!
What am I doing wrong?
Worth to mention my project uses vue 2.0, vue-router, vuex with SSR

I'm looking at two apparent problems.
First, it looks like your code diverges from the vue-router docs in calling require() instead of import().
See it here
https://router.vuejs.org/guide/advanced/lazy-loading.html
The improved version of your child.route.js file is
import ChildHome from "";
import ChildContact from "";
export default [
{
path: '',
name: 'childHome',
component: ChildHome
},
{
path: 'about',
name: 'childAbout',
component: () => import("./components/about.vue")
},
{
path: 'contact',
name: 'childContact',
component: ChildContact
},
]
There is a chance that this could resolve whatever lazy loading problems you may have. There is also a chance that it's inconsequential, and if so, read on.
Second issue, there is a bit of a conundrum with the /child route, and vue-router is picky with these kinds of things. Your parent route file has a component for the /child route:
path: '/child',
component: resolve => require(['app/modules/root'], resolve),
Then your child route file also has a component for this route:
path: '',
name: 'childHome',
component: ChildHome
In this case, the child '' route is the same as /child from the children. Vue is very likely confused when two components are loaded for one route. Clear this up and your problems should go away.

Parent route
import ChildRoutes from "app/modules/child.route”;
routes: [
...ChildRoutes,
]
child.route.js
export default [
{
path: '/child',
component: () => import ('#/app/modules/root'), <-- Just verify this path,
children: ...
}
]

Related

How to add a outside layout to vue component

I wanted to change my vue route from /dashboards/dashboard to just /dashboard. How to achieve these using this code
import Layout2 from '#/layout/Layout2'
export default [
{
path: '/dashboards',
component: Layout2,
children: [
{
path: 'dashboard',
name: 'dashboard',
component: () => import('#/components/dashboards/Dashboard')
}
]
}
]
I have tried putting these code but how can I add the layout2 if the component is already added?
export default [
{
path: '/dashboard',
name: 'dashboard',
component: () => import('#/components/dashboards/Dashboard')
}
]
If vue-router document
Note that nested paths that start with / will be treated as a root
path. This allows you to leverage the component nesting without having
to use a nested URL.
You can do
import Layout2 from '#/layout/Layout2'
export default [
{
path: '/',
component: Layout2,
children: [
{
path: 'dashboard',
name: 'dashboard',
component: () => import('#/components/dashboards/Dashboard')
}
]
}
]

Default router: make id persist to all children

I want to have an id to persist through all routes.
e.g. www.website.com/#/:id/routes
I have tried to do the following:
export default new Router({
routes: [
{
path: '/:id/',
props: true,
component: FirstView,
children: [
{
path: '/',
name: 'Second',
component: SecondView
}
]
}
]
});
but i cant get the :id to persist. Any ideas?
You've specified your nested route path as /, which makes the router treat it as the root path instead of prefixing with /:id in the parent route.
Here's a simple demonstration of nesting routes.

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 routing working only partially.

My App works just fine, if I put routes without childrens (nesting) but I tried to nest it just now and converted my routes to this: in routes.js
import alphabetsPage from './components/views/pages/alphabets.vue'
import dictionaryPage from './components/views/pages/dictionary.vue'
import numbersPage from './components/views/pages/numbers.vue'
import LayoutView from './components/views/Layout.vue'
const routes = [{
path: '/',
name: 'Home',
component: LayoutView,
children: [{
path: 'basic',
name: 'Basic',
component: alphabetsPage,
children: [{
path: 'alphabets',
name: 'Aphabets',
component: alphabetsPage
},
{
path: 'numbers',
name: 'Numbers',
component: numbersPage
}]
}]
}]
export default routes
If I go to / or click on route <router-link to="/basic/alphabets" tag="li"><a>numbers</a></router-link> I can see the alphabetsPage component, however if I go click on <router-link to="/basic/numbers" tag="li"><a>numbers</a></router-link> the route doesn't work. I have a numbersPage componet working.
This must be from the routes, because, if I don't use children and just define the path in routes as /basic/numbers or /basic/alphabets it works.
Children should be shown somewhere.
Your alphabetsPage do not have in template
const alphabetsPage = {
template: '<div>/basic/alphabets <router-view></router-view></div>'
}
https://jsfiddle.net/6fvL1xwc/

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.