Suspense

  • 等待异步组件时渲染一些额外内容,让应用有更好的用户体验(内置组件,不需要引入)
  • 其实和2.x中的路由懒加载差不多

传统写法:效果就是 只要 子组件 还没有 引入成功,整个父组件都不会进行渲染,即所有DOM一起渲染,父组件于子组件视图一起展示 (网络慢的时候明显)

缺点:页面加载慢,加载的快慢取决于 最慢的那个加载的速度 (木桶原理既视感…)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<!-- 父组件 -->
<h1>this is parent</h1>
<i-son></i-son>
</template>
<script>
import iSon from "./injectSon.vue";
export default {
components: {iSon},
};
</script>

<style>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
<template>
<!-- 子组件 -->
<h2>this is son</h2>
</template>

<script>
export default {
}
</script>

<style>
</style>

异步加载组件:子组件不需要改变,父组件引入defineAsyncComponent,来实现异步组件的加载,即先加载父组件,然后在加载 子组件 (网络慢的时候明显)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<!-- 父组件 -->
<h1>this is parent</h1>
<i-son></i-son>
</template>
<script>
// import iSon from "./injectSon.vue"; //同步引入
import {defineAsyncComponent} from "vue";
const iSon = defineAsyncComponent(()=>import("./injectSon.vue")); //异步引入
export default {
components: {iSon},
};
</script>

<style>
</style>

但是以上写法,还是有点问题的,因为 如果 有一个子组件加载的特别特别慢,用户可能以为没东西了呢,其实是因为加载的太慢,还没加载出来,此时Suspense横空出世(据说还不是很稳定目前 2022/3/24)

Suspense底层是通过具名插槽实现的,所以我们写的时候,需要用template包裹,一个是 v-slot:default 用来放置真正要展示的数据;一个是 v-slot:fallback 用来放置 提示 加载中 之类的东西;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<template>
<!-- 父组件 -->
<h1>this is parent</h1>
<!-- Suspense是内置组件,不需要再引入 -->
<Suspense>
<!-- 内置封装了两个实名插槽,实名插槽需要用template包裹 -->
<template v-slot:default>
<i-son></i-son>
</template>

<template v-slot:fallback>
<h3>加载中~~~</h3>
</template>

</Suspense>
</template>
<script>
// import iSon from "./injectSon.vue"; //同步引入
import { defineAsyncComponent } from "vue";
const iSon = defineAsyncComponent(() => import("./injectSon.vue")); //异步引入
export default {
components: { iSon },
};
</script>

<style>
</style>

效果如下图所示

Suspense