How to display a “loading” animation while a lazy-loaded route component is being loaded?

前端 未结 3 2052
不知归路
不知归路 2020-12-13 00:38

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.

相关标签:
3条回答
  • 2020-12-13 01:10

    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.

    0 讨论(0)
  • 2020-12-13 01:15

    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()
    })
    
    0 讨论(0)
  • 2020-12-13 01:26

    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.

    0 讨论(0)
提交回复
热议问题