推荐两个vue超实用的官方内置组件Teleport和Suspense
前言
先直入主题,这文章要介绍的两个内置组件分别是Teleport和Suspense。 之前vue3刚出来就知道增加了Teleport这个内置组件,作用大概是类似传送门,把某个DOM传送到别个一个DOM结构中展示,但最近做某个需求首次使用才觉得Teleport真香啊,太方便了; 而Suspense 组件侧是用于处理异步组件加载时的用户体验的组件。下面分别细说它们的作用、用法和注意事项。
Suspense 组件
作用简述
Suspense用于处理异步组件加载时的用户体验。它可以在组件加载完成前展示一个你自定义的效果,并在组件加载完成后隐藏它。这对于优化用户视觉体验,特别是在组件需要从服务器异步加载时是相当有用。
Suspense 基本用法
Suspense 组件能接受两个插槽分别是#default 和 #fallback。#default 插槽主要用于放置需要加载的组件,而 #fallback 插槽侧用于在组件加载期间想要显示的内容。
代码示例
<template>
<Suspense>
<template #default>
<MyComponent />
</template>
<template #fallback>
<div>加载中你想要显示的内容...</div>
</template>
</Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
const MyComponent = defineAsyncComponent(() => import('./MyComponent.vue')),
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
上述例子中,当 MyComponent 正在加载时,用户会看到#fallback中你想要展示的内容。一旦组件加载完成,Suspense 将自动切换到 MyComponent中。
Suspense 进阶用法
自定义超时时间: 可以通过 timeout 属性来设置 Suspense 在显示内容之前的等待时间。这样能防止在组件快速加载时显示时间过于短暂出现闪一下的效果。
<Suspense timeout="500">
逻辑内容
</Suspense>
2
3
多个异步组件优先级: 当页面中有多个异步组件时,Suspense 可以按需加载组件,先加载的组件会先显示,而内容会在所有组件加载完成前一直显示。
<template>
<Suspense>
<template #default>
<MyComponentA />
<MyComponentB />
</template>
<template #fallback> 加载中的内容 </template>
</Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
const MyComponentA = defineAsyncComponent(() => import('./MyComponentA.vue'))
const MyComponentB = defineAsyncComponent(() => import('./MyComponentB.vue'))
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
动态组件结合 Suspense: Suspense能和 Vue 的动态组件 <component :is="isComponent">
一起使用,方便处理动态加载的组件。
<template>
<Suspense>
<template #default>
<component :is="isComponent" />
</template>
<template #fallback>
加载中显示的内容
</template>
</Suspense>
</template>
2
3
4
5
6
7
8
9
10
**Suspense 结合 SSR **: 在服务端渲染(SSR)环境中,Suspense 会等待所有异步组件加载完成后再渲染页面,这可以确保客户端和服务器端的渲染结果一致。Suspense 的错误处理: 如果异步组件加载失败,Suspense 并不会自动处理错误。它需要我们在组件的 onErrorCaptured钩子中处理错误,或者使用全局的错误处理机制。
<script setup>
import { defineAsyncComponent,onErrorCaptured } from 'vue';
const MyComponent = defineAsyncComponent(() => import('./MyComponent.vue')),
const error = ref(null);
onErrorCaptured((err) => {
error.value = err;
return false; // 阻止错误冒泡
});
</script>
2
3
4
5
6
7
8
9
10
11
Teleport 组件
作用简述
Teleport 组件我们将组件的渲染结果“传送”到 DOM 树中的另一个位置,而不会影响到组件自身的层级关系。这在处理模态对话框、固定定位元素、或者任何需要脱离当前组件层级结构的元素时非常有用。
Suspense 基本用法
Teleport 组件接受一个 to 属性,该属性指定目标元素的选择器。Teleport 的子元素将会被插入到由 to 目标属性指定的元素中展现出来。
代码示例
<template>
<Teleport to="#my-root">
<div id="my-modal" class="modal">
<!-- 想要展示的内容 -->
</div>
</Teleport>
</template>
2
3
4
5
6
7
上述示例中,#my-modal
元素将被传送到具有 id="my-root"
的元素中,无论该元素在组件树中的哪个位置。
Suspense 进阶用法
动态 to 属性: to 属性可以是动态的,也就是说可以根据组件的状态或用户的交互来改变传送的目标。
<Teleport :to="targetElement">
<!-- 想要展示的内容 -->
</Teleport>
2
3
禁用 Teleport: 可以使用 disabled 属性来临时禁用 Teleport 的功能,这在某些条件下不希望进行传送时很有用。
<Teleport to="#my-root" :disabled="!showModal">
<!-- 想要展示的内容 -->
</Teleport>
2
3
多个 Teleport 实例: 可以在同一个组件中使用多个 Teleport 实例,将不同的部分传送到不同的目标位置。事件冒泡: 使用 Teleport 时要注意事件冒泡的问题。由于元素被传送到不同的位置,事件可能会冒泡到目标元素而非原始的组件树。在处理点击或其他事件时,你可能需要考虑这一点。条件渲染: 你可以根据条件渲染 Teleport 组件,例如只在需要显示模态框时才传送元素。
<Teleport v-if="showModal" to="#my-root">
<!-- 想要展示的内容 -->
</Teleport>
2
3
Teleport 的注意事项
- Teleport 不能用于根组件,因为根组件必须始终渲染到 #app 或指定的挂载点。
- 当 Teleport 的目标元素不存在时,子元素将不会被渲染。
- Teleport 的子元素不会影响其周围的兄弟元素,因此可以用于创建浮动或覆盖元素,而不干扰页面的布局流。
小结
- Teleport 和 Suspense 是 Vue3 中两个重要的内置组件,分别用于处理组件渲染位置和异步组件加载时的用户体验。
- Teleport 使得组件可以灵活地渲染到文档的任意位置,而 Suspense 则确保了异步组件加载过程中的平滑过渡。
- 正确使用这两个组件可以显著提升应用的性能和用户体验,特别是在处理复杂的UI场景时。如果那里写的不对或者有什么建议欢迎大佬们指点一二