惊艳!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天前
|
开发工具 iOS开发 MacOS
基于Vite7.1+Vue3+Pinia3+ArcoDesign网页版webos后台模板
最新版研发vite7+vue3.5+pinia3+arco-design仿macos/windows风格网页版OS系统Vite-Vue3-WebOS。
54 10
|
1月前
|
缓存 前端开发 大数据
虚拟列表在Vue3中的具体应用场景有哪些?
虚拟列表在 Vue3 中通过仅渲染可视区域内容,显著提升大数据列表性能,适用于 ERP 表格、聊天界面、社交媒体、阅读器、日历及树形结构等场景,结合 `vue-virtual-scroller` 等工具可实现高效滚动与交互体验。
236 1
|
1月前
|
缓存 JavaScript UED
除了循环引用,Vue3还有哪些常见的性能优化技巧?
除了循环引用,Vue3还有哪些常见的性能优化技巧?
141 0
|
2月前
|
JavaScript
vue3循环引用自已实现
当渲染大量数据列表时,使用虚拟列表只渲染可视区域的内容,显著减少 DOM 节点数量。
89 0
|
4月前
|
JavaScript 前端开发 API
Vue 2 与 Vue 3 的区别:深度对比与迁移指南
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,在过去的几年里,Vue 2 一直是前端开发中的重要工具。而 Vue 3 作为其升级版本,带来了许多显著的改进和新特性。在本文中,我们将深入比较 Vue 2 和 Vue 3 的主要区别,帮助开发者更好地理解这两个版本之间的变化,并提供迁移建议。 1. Vue 3 的新特性概述 Vue 3 引入了许多新特性,使得开发体验更加流畅、灵活。以下是 Vue 3 的一些关键改进: 1.1 Composition API Composition API 是 Vue 3 的核心新特性之一。它改变了 Vue 组件的代码结构,使得逻辑组
1492 0
|
6天前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
73 2
|
3月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
522 0
|
3月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
4月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
528 77
|
2月前
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
97 0