vue3中的异步组件

什么是异步组件

在Vue中,当我们注册全局或局部组件时,它们都是同步地被“立即解析并加载”的。这意味着在我们的程序初始化时,所有组件都会通过网络被下载到内存中,并且在内存中占用一定的资源。预加载所有组件会将页面的初始加载时间和性能降低,尤其是在移动设备上。为了避免这种情况,Vue.js 提供了异步组件。

为什么要使用异步组件

异步组件可以将我们的组件分开打包,按需要加载,这样可以减轻初始页面加载时间和减少资源浪费。当我们需要和路由配合使用时,异步组件也能帮助我们实现按需加载和动态导入。这样可以在调用组件时再切换路由实现动态加载器组件,有助于提高应用程序的性能和响应速度。

定义异步组件

Vue3中使用defineAsyncComponent() 来定义异步组件,该API的入参是一个返回组件选项的函数,需要使用 () => import() 函数来导入组件。

defineAsyncComponent 方法接收一个返回 Promise 的加载函数。这个 Promise 的 resolve 回调方法应该在从服务器获得组件定义时调用。我们也可以调用 reject(reason) 表明加载失败。

import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => {
  return new Promise((resolve, reject) => {
    // ...从服务器获取组件
    resolve(/* 获取到的组件 */)
  })
}) 

ES 模块动态导入也会返回一个 Promise,所以我们会将它和 defineAsyncComponent 搭配使用。类似 Vite 和 Webpack 这样的构建工具也支持此语法 (并且会将它们作为打包时的代码分割点),因此我们也可以用它来导入 Vue 单文件组件:

import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() =>
  import('./components/MyComponent.vue')
)

上面代码得到的 AsyncComponent 是一个外层包装过的组件,仅在页面需要它渲染时才会调用加载内部实际组件的函数。

示例代码:
使用 defineAsyncComponent 函数来定义异步组件,它返回一个组件对象:

import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => import('./MyComponent.vue'))
export default {
  components: {
    AsyncComponent
  }
}

上面定义了一个异步组件,组件通过 components 对象进行注册。

异步组件的加载与错误状态

我们在进行异步操作时,不可避免地会涉及到网络加载慢和加载错误的情况,vue在设计defineAsyncComponent() 组件时也考虑到了这种情况,它为我们提供了两个配置项即:加载异步组件时使用的组件loadingComponent和加载失败后展示的组件errorComponent。我们需要创建两个自定义组件LoadingComponent.vue 和 ErrorComponent.vue组件,作为上面两个配置项使用
示例代码如下

const AsyncComp = defineAsyncComponent({
  // 加载函数
  loader: () => import('./MyComponent.vue'),
  // 加载异步组件时使用的组件
  loadingComponent: LoadingComponent,
  // 展示加载组件前的延迟时间,默认为 200ms
  delay: 200,

  // 加载失败后展示的组件
  errorComponent: ErrorComponent,
  // 如果提供了一个 timeout 时间限制,并超时了
  // 也会显示这里配置的报错组件,默认值是:Infinity
  timeout: 3000
})

上述代码在页面加载时,先加载LoadingComponent组件,在加载组件显示之前有一个默认的 200ms 延迟。如果加载失败,则会调用ErrorComponent组件,还可以指定一个超时时间timeout,在请求耗时超过指定时间时也会渲染报错组件。

搭配 Suspense 使用

什么是Suspense

Suspense是一个内置的组件,可以将子组件的加载状态统一管理,包括异步组件的加载状态。它可以在异步加载组件的时候有一个loading状态,等异步组件创建好之后,再显示组件。

Suspense 组件有两个插槽:#default 和 #fallback。两个插槽都只允许一个直接子节点。

在初始渲染时,Suspense 将在内存中渲染其默认的#default插槽内容。如果在这个过程中遇到任何异步依赖,则会进入挂起状态。在挂起状态期间,展示的是#fallback后备内容。当所有遇到的异步依赖都完成后,Suspense 会进入完成状态,并将展示出默认插槽#default的内容。

如果在初次渲染时没有遇到异步依赖,Suspense会直接进入完成状态。

进入完成状态后,只有当默认插槽#default的根节点被替换时,Suspense才会回到挂起状态。组件树中新的更深层次的异步依赖不会造成 Suspense回退到挂起状态。

发生回退时, #fallback后备内容不会立即展示出来。相反,Suspense在等待新内容和异步依赖完成时,会展示之前 #default 插槽的内容。这个行为可以通过一个 timeout prop 进行配置:在等待渲染新内容耗时超过 timeout 之后,Suspense 将会切换为展示 #fallback后备内容。若 timeout 值为 0 将导致在替换#default 默认内容时立即显示 #fallback后备内容。

Suspense 事件

Suspense 组件会触发三个事件:pending、resolve 和 fallback。pending 事件是在进入挂起状态时触发。resolve 事件是在 default 插槽完成获取新内容时触发。fallback 事件则是在 fallback 插槽的内容显示时触发。

异步组件的suspensible特性

异步组件默认就是“suspensible”的。这意味着如果组件关系链上有一个 Suspense,那么这个异步组件就会被当作这个 Suspense的一个异步依赖。在这种情况下,加载状态是由 Suspense 控制,而该组件自己的加载、报错、延时和超时等选项都将被忽略。

异步组件也可以通过在选项中指定 suspensible: false 表明不用 Suspense 控制,并让组件始终自己控制其加载状态。

异步组件和Suspense配合使用的示例代码

<template>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <p>loading...</p>
    </template>
  </Suspense>
</template>

关于Vue3中的异步组件就聊到这里,喜欢的小伙伴点赞关注收藏哦

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Vue3异步组件可以使用defineAsyncComponent函数进行定义。它会返回一个组件对象,可以在需要时进行动态加载。而Suspense组件则是用于处理异步组件加载时的“等待”状态,它可以显示一个自定义的“等待组件,直到异步组件加载完成并渲染出来。 具体来说,在使用defineAsyncComponent定义异步组件时,可以在组件选项添加loading选项,用于指定Suspense组件的“等待组件。这样,在异步组件加载完成前,Suspense组件会显示loading选项指定的组件,等异步组件加载完成后,再渲染出异步组件。 举个例子,假设我们有一个异步组件如下: ```vue <template> <div>异步组件内容</div> </template> <script> export default { name: 'AsyncComponent', // ... 异步加载组件 } </script> ``` 我们可以使用defineAsyncComponent函数来定义它,并添加loading选项: ```js import { defineAsyncComponent } from 'vue' const AsyncComponent = defineAsyncComponent({ name: 'AsyncComponent', loader: () => import('./AsyncComponent.vue'), loading: { template: '<div>加载...</div>' } }) ``` 然后,在需要使用异步组件的地方,我们可以用Suspense组件包裹: ```vue <template> <Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <div>等待...</div> </template> </Suspense> </template> ``` 这样,在异步组件加载完成前,Suspense组件会显示loading选项的内容;加载完成后,就会渲染出异步组件的内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九仞山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值