Home > Net >  Lazy loading & loading states with vue-router, vite & vuejs 2.x
Lazy loading & loading states with vue-router, vite & vuejs 2.x

Time:10-10

I'm migrating an old project from vue-cli to vite. I followed the migration guide and everything worked great, but there's something it's not working, or at least, not as intended, when I was using vue-cli I tried to implement the loading states as shown in their documentation but then I saw the following pull request explaining how to achieve the wanted behavior (with the downside of losing navigation guards on those routes).

Now, after migrating I noticed that neither the loading/error components are rendered at all, even setting a timeout really small, however, I see in the networking tab that my components are being loaded, but never rendered.

Do you have any suggestions of why might this occur?.

// This is the lazyLoadView that was working before migrating to vite.

function lazyLoadView(AsyncView) {
  const AsyncHandler = () => ({
    component: AsyncView,
    // A component to use while the component is loading.
    loading: import("./components/loaders/loader.vue").default,
    // A fallback component in case the timeout is exceeded
    // when loading the component.
    error: import("./components/loaders/error.vue").default,
    // Delay before showing the loading component.
    // Default: 200 (milliseconds).
    delay: 1,
    // Time before giving up trying to load the component.
    // Default: Infinity (milliseconds).
    timeout: 2,
  });
  return Promise.resolve({
    functional: true,
    render(h, { data, children }) {
      // Transparently pass any props or children
      // to the view component.
      return h(AsyncHandler, data, children);
    },
  });
}

And the routes I have:

const routes = [
    {
        path: "/foo/",
        component: () => lazyLoadView(import("./components/bar.vue")),
    }
]

Let me know if you find why might this be happening.

CodePudding user response:

So I figured out:

Looks like the loading & error components were also lazy loaded, they were skipped. So continued trying to obtain the main one until shown (that's why didn't render the loading besides of only showing a message).

So in order to fix it I had to import them at the top and include them in the lazyLoadView like this:

//These two imports at the top
import loaderComp from "./components/loaders/loader.vue";
import errorComp from "./components/loaders/error.vue";

function lazyLoadView(AsyncView) {
  const AsyncHandler = () => ({
    component: AsyncView,
    // A component to use while the component is loading.
    // must NOT be lazy-loaded
    loading: loaderComp,
    // A fallback component in case the timeout is exceeded
    // when loading the component.
    // must NOT be lazy-loaded
    error: errorComp,
    // Delay before showing the loading component.
    // Default: 200 (milliseconds).
    delay: 1,
    // Time before giving up trying to load the component.
    // Default: Infinity (milliseconds).
    timeout: 2,
  });
  return Promise.resolve({
    functional: true,
    render(h, { data, children }) {
      // Transparently pass any props or children
      // to the view component.
      return h(AsyncHandler, data, children);
    },
  });
}
  • Related