当我像这样填写
component
中的 createRouter()
字段时:
{
path: '/article/post',
name: 'article-post',
component: defineAsyncComponent({
loader: () => import('@/views/article-post/index.vue'),
loadingComponent: () => import('@/views/article-post/skeleton.vue'),
}),
},
好像不起作用。 我希望它在实际页面加载时显示加载页面。
我该怎么做?
loadingComponent
值必须是组件定义,并且本身不能是异步组件:
import { createRouter } from 'vue-router'
import { defineAsyncComponent } from 'vue'
import Skeleton from '@/views/article-post/skeleton.vue'
export default createRouter({
routes: [
{
path: '/article/post',
name: 'article-post',
component: defineAsyncComponent({
loader: () => import('@/views/article-post/index.vue'),
//loadingComponent: () => import('@/views/article-post/skeleton.vue'), ❌ cannot be dynamic import
loadingComponent: Skeleton ✅
}),
},
]
})
另请注意,加载组件 (
Skeleton
) 仅显示一次,即,如果组件定义尚未在缓存中。这个 Codesandbox 在 loader()
中添加了人工延迟来进行演示。
您可以像这样异步加载组件:
{
path: '/article/post',
name: 'article-post',
component: () => ({
component: import('@/views/article-post/index.vue')
loading: import('@/views/article-post/skeleton.vue')
})
},
如果你想在vue-router中使用defineAsyncComponent并且没有收到警告,你可以使用这样的包装器:
import {defineAsyncComponent, h} from 'vue'
import Loading from 'shared/components/loading.vue'
function lazyLoad(component_name, params = {}) {
return {
render() {
const async_component = defineAsyncComponent({
loader: () => import(`pages/${component_name}`),
loadingComponent: Loading,
...params
})
return h(async_component)
}
}
}
然后将其注入到您的路线中:
{
path: '/',
name: 'welcome',
component: lazyLoad('Welcome')
}
想添加到@六弦工答案,但这太长了,无法容纳评论。
如果您在
/pages
中有嵌套文件夹(例如 /pages/explore/Search.vue
)并且想要传递 lazyLoad("explore/Search")
,则该解决方案将不起作用。这与 Vite(或更具体地说是我认为的 Rollup)处理这些导入的方式有关。 在本期中了解有关此问题的更多信息以及潜在的修复方法。我认为最干净的就是这个(使用 TypeScript):
const asyncRoute = (path: string) =>
defineComponent({
render() {
const component = defineAsyncComponent({
loader: () => {
const comps = import.meta.glob<false, string, Component>(
"../pages/**/*.vue",
);
return comps[`../pages/${path}.vue`]();
},
loadingComponent: SomePlaceholderComponent,
});
return h(component);
},
});