如何在 [email protected] (Vue3) 中使用 createAsyncComponent?

问题描述 投票:0回答:5

当我像这样填写

component
中的
createRouter()
字段时:

{
    path: '/article/post',
    name: 'article-post',
    component: defineAsyncComponent({
      loader: () => import('@/views/article-post/index.vue'),
      loadingComponent: () => import('@/views/article-post/skeleton.vue'),
    }),
},

好像不起作用。 我希望它在实际页面加载时显示加载页面。

我该怎么做?

vue.js vue-router vuejs3 vue-router4
5个回答
4
投票

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()
中添加了人工延迟来进行演示。


1
投票

您可以像这样异步加载组件:

{
    path: '/article/post',
    name: 'article-post',
    component: () => ({
        component: import('@/views/article-post/index.vue')
        loading: import('@/views/article-post/skeleton.vue')
    })
},

1
投票

如果你想在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')
}

0
投票

想添加到@六弦工答案,但这太长了,无法容纳评论。

如果您在

/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); }, });



-2
投票
注意

不要将异步组件用于路由。异步组件仍然可以在路由组件内部使用,但路由组件本身只是动态导入。

© www.soinside.com 2019 - 2024. All rights reserved.