I have split my app into multiple chunks with webpack\'s code splitting feature so that the entire application bundle isn\'t downloaded when the user visits my webpage.
For what it's worth, I'll share what I ended up doing for my situation.
I'm using Vuex so it was easy to create an app-wide "loading" state which any component can access, but you can use whatever mechanism you want to share this state.
Simplified, it works like this:
function componentLoader(store, fn) {
return () => {
// (Vuex) Loading begins now
store.commit('LOADING_BAR_TASK_BEGIN');
// (Vuex) Call when loading is done
const done = () => store.commit('LOADING_BAR_TASK_END');
const promise = fn();
promise.then(done, done);
return promise;
};
}
function createRoutes(store) {
const load = fn => componentLoader(store, fn);
return [
{
path: '/foo',
component: load(() => import('./components/foo.vue')),
},
{
path: '/bar',
component: load(() => import('./components/bar.vue')),
},
];
}
So all I have to do is wrap every () => import()
by my load()
function which takes care of setting the loading state. Loading is determined by observing the promise directly instead of relying on router-specific before/after hooks.
you can use this code for gobel route in one project of vuejs
const router = new Router({
routes: [
{ path: '/', name: 'home', component: Home },
{ path: '/about', name: 'about', component: About }
]
})
router.beforeResolve((to, from, next) => {
// If this isn't an initial page load.
if (to.name) {
// Start the route progress bar.
NProgress.start()
}
next()
})
router.afterEach((to, from) => {
// Complete the animation of the route progress bar.
NProgress.done()
})
You can use navigation guards to activate/deactivate a loading state that shows/hides a loading component:
If you would like to use something like "nprogress" you can do it like this:
http://jsfiddle.net/xgrjzsup/2669/
const router = new VueRouter({
routes
})
router.beforeEach((to, from, next) => {
NProgress.start()
next()
})
router.afterEach(() => {
NProgress.done()
})
Alternatively, if you want to show someting in-place:
http://jsfiddle.net/h4x8ebye/1/
Vue.component('loading',{ template: '<div>Loading!</div>'})
const router = new VueRouter({
routes
})
const app = new Vue({
data: { loading: false },
router
}).$mount('#app')
router.beforeEach((to, from, next) => {
app.loading = true
next()
})
router.afterEach(() => {
setTimeout(() => app.loading = false, 1500) // timeout for demo purposes
})
Then in the template:
<loading v-if="$root.loading"></loading>
<router-view v-else></router-view>
That could also be easily encapsulated in a very small component instead of using the $root
component for the loading state.