Vue router shows lazy-loaded route components only once

1.6k views Asked by At

I'm using Laravel 5.3 as a backend and Vue combo (Vue 2.1.6 + Vue-Router + vue resource + gulp/webpack etc) as my frontend. My project is a single page application (SPA).

Everything worked fine until I decided to load each page with lazy loading. https://router.vuejs.org/en/advanced/lazy-loading.html

This is my app.js:

import store from './components/vuex/store.js'
import App from './components/App.vue';

const UserPage = r => require.ensure([], () => r(require('./components/views/UserPage.vue')), 'group-ip')
const UserSettings = resolve => require(['./components/views/UserSettings.vue'], resolve)            // r => require.ensure([], () => r(require('./components/views/PlayerSettings.vue')), 'group-settings')
const Hub = resolve => require(['./components/views/Hub/Hub.vue'], resolve)


const routes = [
  { path: '/', component: UserPage },
  { path: '/settings', component: UserSettings },
  { path: '/user/:id', component: Hub },
  { path: '*', redirect: '/' }
]

const router = new VueRouter({
  mode: 'history',
  routes
})


const app = new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app');

My problem is that... everything (I mean every page) works, but only ONCE. As soon as I click on the link to /settings or /user/blahblah it loads all components just fine, but when I come back to the previously visited page, it doesn't load its component. Vue devtools doesn't even show that component in the root tree (when I use keep-alive to cache my routes, it shows them as inactive) and there are no warnings at all. When I reload the page it I can use them again, but just once. And so on, and so on...

When I stop using lazy loading and just include it like this

import Hub from './components/views/Hub/Hub.vue'

It works all the time.

1

There are 1 answers

0
Georgi Antonov On

Here is how i deal with lazy loading of router components This will work only if you use babel/webpack/vue-cli etc... since its ES6

inside my router folder i have

index.js

import Vue from 'vue';
import Router from 'vue-router';
import lazyLoading from './lazyLoading';

Vue.use(Router);

const router = new Router({
    mode: 'history',
    linkActiveClass: 'active-route',
    routes: [
        {
            path: '/',
            name: 'app',
            components: {
                default: lazyLoading('YourComponent'), 
            },
        },
        {
            path: '/somepath',
            name: 'somename',
            components: {
                default: lazyLoading('YourSecondComponent'),
            },
        },
        {
            path: '*',
            redirect: '/',
        },
    ],
});

export default router;

If your component is with name index.vue inside folder do this.

Here adjust the import url to find the proper path in your project.

lazyLoading('YourFolder', true)

lazyloading.js

export default (name, index = false) => () => import(`../components/${name}${index ? '/index' : ''}.vue`);