inca / voie

[UNMAINTAINED] Simple Vue.js router / layout manager
141 stars 7 forks source link

Lazyload components #21

Open airtonix opened 8 years ago

airtonix commented 8 years ago

We're at the optimisation stage of the app, we have the project being completely built with vue-cli.

I'd like to start lazy loading components:

application.add(RouteNames.AUCTION_CREATE_PURPOSE, {
    path: PathNames.AUCTION_CREATE_PURPOSE,
    component: new Promise( (resolve, reject) => {
        require.ensure(['./steps/purpose.vue'], (require) => {
            let PurposeFormView = require('./steps/purpose.vue');
            console.log('ready', PurposeFormView);
            resolve(PurposeFormView);
        });
    })
});

One of your motivations for creating Voie was that you wanted delay rendering the component until the data was ready.

I posit that treating state.component as a promise will take us further:

application.add(RouteNames.AUCTION_CREATE_PURPOSE, {
    path: PathNames.AUCTION_CREATE_PURPOSE,
    component (resolve, reject) { require(['./steps/purpose.vue'], resolve); }
});
inca commented 8 years ago

Well, basically this feature is already supported, please check out this test case: https://github.com/inca/voie/blob/master/test/specs/transitions.js#L97

Teknologica commented 8 years ago

Would this work with nested views though? Looking at the Vue example it seems that having something similar in Voie would be nice.

Vue.component('async-webpack-example', function (resolve) {
  require(['./my-async-component'], resolve)
})

Akin to this

Router.add({
    name: 'dashboard',
    path: '/dashboard',
    parent: 'main',
    component: function (resolve) {
        require(['./dashboard.vue'], resolve);
    }
});

P.S. Also how would the enter hook work in conjunction with v-view? I tried something along the lines of this (see below) with no success.

enter: new Promise((resolve, reject) => {
    require.ensure(['./dashboard.vue'], () => {
        const component = require('./dashboard.vue');
        resolve({component});
    });
})
airtonix commented 8 years ago

Same here, tried doing this like so:

enter: (context) => {
  return service.withMethodReturningAPromise()
    .then(service.anotherPromiseReturningMethod)
    .then(service.yetAnotherPromiseReturningMethod)
    .then( () => {
        return new Promise((resolve, reject) => {
            require.ensure(['./dashboard.vue'], (component) => {
                log({component});
                resolve({component});
            });
        })
    });
}

component ends up being what I expect it to be, but webpack doesn't actually code split.