异步组件

使用骨架屏理解异步组件。

sync.vue:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<template>
<div class="sync">
<div class="sync-content">
<div><img :src="data.url" alt="">{{ data.name }}</div>
<hr>
<div class="sync-pop">
<div>{{ data.desc }}</div>
<div>&nbsp;</div>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { axios } from "@/server/axios"

interface Data {
data: {
name: string,
age: number,
url: string,
desc: string
}
}

// ES7中引入的顶层await技术
// 可以直接在一个模块的最外层使用await
// 这让整个模块看起来像一个巨大的async函数
// mock数据将在发送请求的2秒后收到
const { data } = await axios.get<Data>("./data.json")
</script>

<style scoped lang="scss">
.sync {
width: 500px;
background-color: #eee;
padding: 10px;
.sync-content {
div {
font-size: 12px;
img {
width: 50px;
height: 50px;
border-radius: 50%;
}
}
}
}
</style>

skeleton.vue:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<template>
<div class="sk">
<div class="sk-2">
<div class="avatar"></div>
<div class="name"></div>
</div>
<hr>
<div class="sk-3"></div>
<div class="sk-3"></div>
</div>
</template>

<style scoped lang="scss">
.sk {
width: 500px;
background-color: #eee;
padding: 10px;
.sk-2 {
display: flex;
align-items: baseline;
.avatar {
width: 50px;
height: 50px;
background-color: #ccc;
border-radius: 50%;
}
.name {
width: 50px;
height: 12px;
background-color: #ccc;
}
}
.sk-3 {
height: 12px;
background-color: #ccc;
&:last-child {
margin-top: 6px;
}
}
}
</style>

App.vue:

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
28
29
30
<template>
<div>
<!-- 展示异步组件必须使用suspense -->
<Suspense>
<!-- 主要展示的组件 -->
<template #default>
<sync></sync>
</template>
<!-- 加载时呈现的组件 -->
<template #fallback>
<skeleton></skeleton>
</template>
</Suspense>
</div>
</template>

<script setup lang="ts">
import { defineAsyncComponent, ref } from 'vue'
import skeleton from './components/expame/skeleton.vue'

// 使用defineAsyncComponent引入异步组件,支持两种书写风格
// 动态组件形式
const sync = defineAsyncComponent(()=> import("@/components/expame/sync.vue"))
// 配置对象形式,几乎用不到
// const sync = defineAsyncComponent({
// loadingComponent: ()=> import("@/components/expame/sync.vue"),
// errorComponent: ...,
// timeout: ...,
// })
</script>

代码分包

vue代码默认只会被打包成一个js文件(主包),使用同步方式引入的组件就在其中。

将组件异步引入,打包后组件就会被实现分包,不会放在主包内,可以缩短首次加载的时间。