惊艳!Vue 3 中使用 Suspense 实现异步组件加载,用户体验 大大大大大 提升!!

简介: 惊艳!Vue 3 中使用 Suspense 实现异步组件加载,用户体验 大大大大大 提升!!

你们是否有过这样的经历:用户抱怨页面加载太慢,而你正在为如何提升用户体验头疼不已?

别担心,我也曾深陷这种“加载地狱”。幸运的是,Vue 3 给我们带来了一个神奇的工具:Suspense。它就像一剂强效药,能瞬间提升我们的用户体验

今天,我将带你一起深入探讨如何在 Vue 3 中使用 Suspense 实现异步组件加载,让你的用户惊呼“哇,太顺滑了!”。

1. 什么是 Suspense?

Suspense 是 Vue 3 提供的一个新特性,用于等待异步组件加载完成后再进行渲染。它使得处理异步操作更加简单和直观,极大地提升了用户体验。

为什么要使用 Suspense?

  • 提升用户体验:避免白屏或加载不完全的情况。
  • 代码更简洁:更好地管理异步组件的加载和错误处理。
  • 更高的可维护性:集中管理加载状态和错误处理。

2. 安装和设置 Vue 3 项目

首先,让我们创建一个新的 Vue 3 项目。如果你还没有安装 Vue CLI,请先安装它:

npm install -g @vue/cli

接着,创建一个新的 Vue 3 项目:

vue create vue-suspense-demo

选择 Vue 3 选项并完成项目创建。然后,进入项目目录并启动开发服务器:

cd vue-suspense-demo
npm run serve

3. 基础用法:异步组件加载

创建异步组件

在 Vue 3 中,使用 defineAsyncComponent 来创建一个异步组件非常简单。我们先创建一个异步组件

AsyncComponent.vue:
<!-- src/components/AsyncComponent.vue -->
<template>
  <div>
    <h1>我是异步加载的组件!</h1>
  </div>
</template>
<script setup>
</script>

使用 Suspense 加载异步组件

接下来,我们在 App.vue 中使用 Suspense 组件来加载这个异步组件:

<!-- src/App.vue -->
<template>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <div>加载中...</div>
    </template>
  </Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() => import('./components/AsyncComponent.vue'));
</script>
<style>
/* 添加一些基本样式 */
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

解释

在上面的代码中,我们使用了 Suspense 组件,并定义了 defaultfallback 模板。当异步组件加载时,fallback 模板中的内容会被显示(例如“加载中...”),而一旦异步组件加载完成,default 模板中的内容(即 AsyncComponent)会替换 fallback 模板中的内容。

4. 高级用法:使用多个异步组件

创建多个异步组件

让我们再创建一个异步组件 AnotherAsyncComponent.vue

<!-- src/components/AnotherAsyncComponent.vue -->
<template>
  <div>
    <h1>我是另一个异步加载的组件!</h1>
  </div>
</template>
<script setup>
</script>

使用 Suspense 加载多个异步组件

我们可以在 App.vue 中同时使用多个异步组件:

<!-- src/App.vue -->
<template>
  <Suspense>
    <template #default>
      <div>
        <AsyncComponent />
        <AnotherAsyncComponent />
      </div>
    </template>
    <template #fallback>
      <div>组件正在加载中...</div>
    </template>
  </Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() => import('./components/AsyncComponent.vue'));
const AnotherAsyncComponent = defineAsyncComponent(() => import('./components/AnotherAsyncComponent.vue'));
</script>
<style>
/* 添加一些基本样式 */
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

解释

这里我们在 Suspense 组件中加载了两个异步组件。当这两个组件都加载完成后,default 模板中的内容会被渲染。

5. 自定义加载和错误处理

自定义加载状态

有时,我们可能希望自定义加载状态的显示样式。我们可以通过在 fallback 模板中使用自定义组件来实现这一点:

<!-- src/components/LoadingComponent.vue -->
<template>
  <div class="loading">
    <p>请稍候,数据正在加载...</p>
  </div>
</template>
<script setup>
</script>
<style scoped>
.loading {
  text-align: center;
  padding: 20px;
}
</style>

App.vue 中使用这个自定义加载组件:

<!-- src/App.vue -->
<template>
  <Suspense>
    <template #default>
      <div>
        <AsyncComponent />
        <AnotherAsyncComponent />
      </div>
    </template>
    <template #fallback>
      <LoadingComponent />
    </template>
  </Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
import LoadingComponent from './components/LoadingComponent.vue';
const AsyncComponent = defineAsyncComponent(() => import('./components/AsyncComponent.vue'));
const AnotherAsyncComponent = defineAsyncComponent(() => import('./components/AnotherAsyncComponent.vue'));
</script>
<style>
/* 添加一些基本样式 */
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

错误处理

在加载异步组件时,有时会遇到错误。我们可以通过 defineAsyncComponent 的选项来处理这些错误:

const AsyncComponent = defineAsyncComponent({
  loader: () => import('./components/AsyncComponent.vue'),
  loadingComponent: LoadingComponent,
  errorComponent: {
    template: '<div>加载失败,请稍后重试。</div>'
  },
  delay: 200,
  timeout: 3000
});

解释

通过定义 loadingComponenterrorComponent,我们可以自定义加载和错误状态的显示。此外,delaytimeout 可以控制加载组件的显示延迟和超时时间。

6. 实战演练:构建一个带有 Suspense 的应用

创建项目结构

我们将创建一个包含多个异步组件的应用,并使用 Suspense 进行管理。项目结构如下:

src/
 components/
   AsyncComponent.vue
   AnotherAsyncComponent.vue
   LoadingComponent.vue
   ErrorComponent.vue
 App.vue
 main.js

配置组件

AsyncComponent.vue

<template>
  <div>
    <h1>我是异步加载的组件!</h1>
  </div>
</template>
<script setup>
</script>

AnotherAsyncComponent.vue

<template>
  <div>
    <h1>我是另一个异步加载的组件!</h1>
  </div>
</template>
<script setup>
</script>

LoadingComponent.vue

<template>
  <div class="loading">
    <p>请稍候,数据正在加载...</p>
  </div>
</template>
<script setup>
</script>
<style scoped>
.loading {
  text-align: center;
  padding: 20px;
}
</style>

ErrorComponent.vue

<template>
  <div class="error">
    <p>加载失败,请稍后重试。</p>
  </div>
</template>
<script setup>
</script>
<style scoped>
.error {
  text-align: center;
  padding: 20px;
  color: red;
}
</style>

配置 App.vue

<template>
  <Suspense>
    <template #default>
      <div>
        <AsyncComponent />
        <AnotherAsyncComponent />
      </div>
    </
template>
    <template #fallback>
      <LoadingComponent />
    </template>
  </Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
import LoadingComponent from './components/LoadingComponent.vue';
import ErrorComponent from './components/ErrorComponent.vue';
const AsyncComponent = defineAsyncComponent({
  loader: () => import('./components/AsyncComponent.vue'),
  loadingComponent: LoadingComponent,
  errorComponent: ErrorComponent,
  delay: 200,
  timeout: 3000
});
const AnotherAsyncComponent = defineAsyncComponent({
  loader: () => import('./components/AnotherAsyncComponent.vue'),
  loadingComponent: LoadingComponent,
  errorComponent: ErrorComponent,
  delay: 200,
  timeout: 3000
});
</script>
<style>
/* 添加一些基本样式 */
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

解释

通过这种方式,我们将 Suspense 和自定义加载、错误组件结合起来,实现了一个完整的异步组件加载管理。

7. 性能优化和最佳实践

延迟加载组件

为了进一步优化性能,我们可以在组件即将进入视口时再进行加载。可以使用 IntersectionObserver 来实现这一点:

import { ref, onMounted, defineAsyncComponent } from 'vue';
const LazyComponent = defineAsyncComponent(() => import('./components/LazyComponent.vue'));
export default {
  setup() {
    const isVisible = ref(false);
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          isVisible.value = true;
          observer.disconnect();
        }
      });
    });
    onMounted(() => {
      const target = document.getElementById('lazy-component');
      observer.observe(target);
    });
    return {
      isVisible,
      LazyComponent
    };
  }
};

使用 defineAsyncComponent 的其他选项

defineAsyncComponent 提供了多个选项来优化加载过程:

  • retry: 指定重试次数。
  • onError: 自定义错误处理逻辑。

示例

const LazyComponent = defineAsyncComponent({
  loader: () => import('./components/LazyComponent.vue'),
  retry: 3,
  onError(error, retry, fail, attempts) {
    if (attempts <= 3) {
      retry();
    } else {
      fail();
    }
  }
});

总结

通过本文,我们深入探讨了在 Vue 3 中使用 Suspense 实现异步组件加载的各种方法和最佳实践。

从基础用法到高级应用,再到性能优化,我们全面覆盖了如何提升用户体验的方法。

相关文章
|
3天前
|
JavaScript
vue3- antd design vue 引入iconfont
vue3- antd design vue 引入iconfont
|
11天前
|
缓存 监控 UED
升级 Vue3 时,如何减少打包体积的增加?
升级 Vue3 时,如何减少打包体积的增加?
100 59
|
10天前
|
JavaScript
在vue3中(vite)引入unocss,安装配置unocss
在vue3中(vite)引入unocss,安装配置unocss
|
11天前
|
API UED
升级 Vue3 后,项目的打包体积会有什么变化?
升级 Vue3 后,项目的打包体积会有什么变化?
104 57
|
2天前
|
JavaScript 数据格式
vue3 + Ant design vue formItem 无法使用嵌套的form表单校验
vue3 + Ant design vue formItem 无法使用嵌套的form表单校验
16 1
|
1天前
|
JavaScript 前端开发
vue尚品汇商城项目-day01【4.完成非路由组件Header与Footer业务】
vue尚品汇商城项目-day01【4.完成非路由组件Header与Footer业务】
9 2
|
1天前
|
JavaScript 前端开发
vue尚品汇商城项目-day01【3.项目路由的分析】
vue尚品汇商城项目-day01【3.项目路由的分析】
6 1
|
1天前
|
JavaScript 前端开发 数据安全/隐私保护
vue尚品汇商城项目-day01【5.路由组件的搭建】
vue尚品汇商城项目-day01【5.路由组件的搭建】
5 0
vue尚品汇商城项目-day01【5.路由组件的搭建】
|
2天前
|
JavaScript 索引
vue尚品汇商城项目-day04【25.面包屑处理关键字】
vue尚品汇商城项目-day04【25.面包屑处理关键字】
12 1