In my case Vue3.5 we couldn't use 'defineAsyncComponent' because of the warning.
We couldn't use - UX was worse, it didn't changed route until current route (component) is fully loaded (bad for slow network users).
We customized our async Loader ourselves:
AsyncComponentLoader.ts
import {defineComponent,h,ref,shallowRef,onMounted,onUnmounted,} from'vue';
import RouterLoader from '@/components/shared/RouterLoader.vue';
import ErrorComponent from '@/components/shared/ErrorComp.vue';
interface AsyncComponentOptions {
loader: () => Promise<any>;
loadingComponent?: any;
errorComponent?: any;
}
export function AsyncComponentLoader(options: AsyncComponentOptions) {
const {
loader,
loadingComponent = RouterLoader,
errorComponent = ErrorComponent,
} = options;
return defineComponent({
name: 'AsyncComponentLoader',
props: {},
setup(props, { attrs }) {
const component = shallowRef(loadingComponent);
const error = shallowRef(null);
const isMounted = ref(false); // Use a ref to track mounted state
const loadComponent = async () => {
component.value = loadingComponent;
error.value = null;
try {
const module = await loader();
const loadedComponent = module.default || module;
if (isMounted.value) {
component.value = loadedComponent;
}
} catch (err) {
if (isMounted.value) {
error.value = err;
component.value = errorComponent;
if (!errorComponent) {
console.error(err);
}
}
}
};
onMounted(() => {
isMounted.value = true;
loadComponent();
});
onUnmounted(() => {
isMounted.value = false;
});
return () => (component.value
? h(component.value, { ...attrs, ...props })
: null);
},
});
}
Then in 'routes.ts' define components:
const SomeComp = () => AsyncComponentLoader({
loader: () => import(
/* webpackChunkName: "sports" */
'@/components/some-path/SomeComp.vue'
),
});
const OtherComp = () => AsyncComponentLoader({
loader: () => import(
/* webpackChunkName: "sports" */
'@/components/some-path/OtherComp.vue'
),
});
const routes: RouteRecordRaw[] = [
{
path: routeMap.some.path,
name: routeMap.some.name,
component: SomeComp(),
meta: {
addToSitemap: true,
appPath: true,
},
},
{
path: routeMap.app.path,
name: routeMap.app.name,
component: OtherComp(),
},
importroute makes the homepage/root route render briefly while the correct route is loading. As such, doing this method, withdefineAsyncComponent, let's me control what is shown as a loading fallback.