Как использовать createAsyncComponent в VueRouter@4.0.0 (Vue3)?

Когда я наполняю component поле в createRouter() как это:

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

Похоже, это не работает. Я хочу, чтобы он показывал страницу загрузки, когда загружается фактическая страница.

Как мне это сделать?

5 ответов

В loadingComponent value должно быть определением компонента и не может быть асинхронным компонентом:

      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() демонстрировать.

Если вы хотите использовать defineAsyncComponent в vue-router и не получать предупреждений, вы можете использовать такую ​​оболочку:

      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')
}

Вы можете загружать компоненты асинхронно следующим образом:

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

Я не проверял этот код, но что-то вроде этого:

Что мы делаем:

  1. Синхронный импорт нашего легкого каркасного компонента и;
  2. Указание этой ссылки в качестве нашего загрузочного компонента.

Как только переменная компонента получит асинхронный компонент, он отобразит его вместо загрузки.

Примечание

Не используйте асинхронные компоненты для маршрутов. Асинхронные компоненты по-прежнему можно использовать внутри компонентов маршрута, но сами компоненты маршрута являются просто динамическим импортом.

Другие вопросы по тегам