关于Vue3的新特性Suspense的实验性测试

海星吧 2022-7-20 5130

Suspense 是vue3中将异步组件提升到组件树中的异步组件包容器。

这个组件效果和vue3的异步组件API defineAsyncComponent 相似

其目的都是在组件做异步请求的时候,显示一个loading的等待。

为此我做了一个关于 Suspense 的实验。

我这个项目使用了 tailwind.css 作为减少我样式编写的库,安利一下。

首先准备好两个组件

textBlue.vue
<template>
	<div class="text-blue-400">文字1</div>
</template>
<script setup>
const sleep = (delay = 2000) =>
	new Promise((resp) => setTimeout(() => resp(), delay));
await sleep(2000);
</script>
textGreen.vue
<template>
    <div class="text-green-400">
        文字2
    </div>
</template>
<script setup>
const sleep = (delay = 2000) =>
	new Promise((resp) => setTimeout(() => resp(), delay));
await sleep(2000);
</script>

 

这两个组件中我使用了sleep函数作为异步请求的模拟

 

以下是我实验的index组件。

<template>
	<div class="card">
		<p>测试切换组件</p>
		<p>{{ componentType }}</p>
		<el-radio-group v-model="componentType">
			<el-radio
				v-for="item in types"
				:label="item.label"
				:key="item.label"
			></el-radio>
		</el-radio-group>
		<p>Suspense : </p>
		<transition mode="out-in" name="el-fade-in-linear">
			<Suspense
				@pending="pendingEnv"
				@resolve="resolveEnv"
				@fallback="fallbackEnv"
				:timeout="0"
			>
				<template #default >
					<component :is="componentIs" :key="componentIsKey"></component>
				</template>
				<template #fallback>
					<loadingCmd></loadingCmd>
				</template>
			</Suspense>
		</transition>
	</div>
</template>

<script setup>
import textBlue from "./textBlue";
import textGreen from "./textGreen";
import loadingCmd from "./loading";
import errorCmd from "./error";
import { ref, defineAsyncComponent, computed } from "vue-demi";

const componentType = ref("textBlue");
const componentIs = computed(
	() =>
		types.find((a) => a.label == componentType.value).component || errorCmd
);
const componentIsKey = computed(() => componentType.value || "error");
const types = [
	{
		label: "textBlue",
		component: textBlue,
	},
	{
		label: "textGreen",
		component: textGreen,
	},
];
function pendingEnv() {
	console.log("发生变化");
}
function resolveEnv() {
	console.log("加载完成");
}
function fallbackEnv() {
	console.log("加载 loading");
}

</script>

这是页面的效果。

刚开始看是没啥,但是我组件切换的时候需要异步请求数据,这个时候不希望用户看到没有数据的组件,

给用户一个等待响应的等待页面。

Suspense组件目前有两个插槽,三个事件,一个属性
插槽
一个是 #default
一个是 #fallback
事件
@pending 组件发生变化时
@fallback  组件发生变化后进入fallback插槽
@resolve   组件加载完成后结束fallback插槽的显示进入到业务组件中
default是你放正常的组件时的插槽,fallback是loading状态组件的插槽,
这里有一个很尬的地方,如果不在 Suspense 中使用 timeout这个属性,那么这个loading就只会有一次被显示,
我之前测试了它的事件,结果发现除了第一次进入页面的时候,它会加载loading组件,
在我切换组件的时候,它反而只会触发pending 和 resolve  ,fallback  事件并不会触发,并且#fallback  插槽也不会进入。
在我翻阅文档后才发现这点,当时没有仔细看,后面才发现这个感觉好坑啊。。
 

 

给你们看看没有加timeout的时候是什么样子


这是进入页面时发生的变化,但是我切换组件的时候



可以看到并没有触发fallback函数,也没有像第一次进入的时候加载loading
那再来看看加上timeout = ‘0’是什么样子


可以看到组件被切换的时候,Suspense触发了fallback并进入了loading插槽。

所以这个组件如果需要反复的加载loading的话,还是得使用timeout属性赋值为0才行。

以上是我对这个组件的实验性测试,如果你有什么好的发现或其他想要交流的话,敬请留言。
 
(σ゚∀゚)σ..:*☆ 这里是海星吧,我们下次见,拜拜。
弱鸡程序员年底还在加班
最新回复 (6)
  • 海星吧 2022-7-20
    0 2
    星辰乄 可惜我不是数据算法分析专业的学生,只能做到看懂但做不到分析。 loading的过程只在第一次使用页面时加载,是不是说在组件以及其属性完全相同的情况下只在第一次加载时使用呢? 这个感觉和cook ...
    loading的状态不仅仅只在页面进入时加载,在任何有需要的时候,loading都是可以发生效用的。
    描述一个场景,如果一个管理后台拥有切换布局的功能,那么这个切换的时候会造成大量的render,
    这种比较耗时且可能切换频繁的时候,可以将 Suspense 中的 fallback 作为一个雪碧图 遮挡 页面。
    还有 Suspense 是包裹异步组件的,也就是说不用在 onMounted  hook 中再去调用接口,而是直接在
    script setup 语法糖中调用接口请求数据,然后 让Suspense 进入fallback也是可以的。
    因为被 setup 属性描述的script本身就可以作为一个async 函数使用。
    弱鸡程序员年底还在加班
  • 海星吧 2022-7-21
    0 3
    星辰乄 针对你说的场景,存在两种情况, 第一种,客户端完全的第一次进行服务端请求,或者说客户端的该次请求是在对服务端的请求周期之外,此时本地资源已经释放,这种情况会产生大量render,客户端资源会得到第一 ...
    遇上同行了。
    反正这东西就是拿来参考的,具体情况具体分析,该用到业务中的时候也会有莫名其妙的需求。
    比如老板让你加长loading时间然后告诉甲方要优化得加钱。
    弱鸡程序员年底还在加班
  • 海星吧 2022-7-21
    0 4
    欧派兽 奖励三级精华
    感谢。
    弱鸡程序员年底还在加班
  • 海星吧 2022-7-21
    1 5
    星辰乄 针对你说的场景,存在两种情况, 第一种,客户端完全的第一次进行服务端请求,或者说客户端的该次请求是在对服务端的请求周期之外,此时本地资源已经释放,这种情况会产生大量render,客户端资源会得到第一 ...

    还有这个场景可不是用的复数组件哦,这个是用vue的component内置组件,用is属性来判断需要使用的是那个组件,我目前写了个后台的项目就是用的component来切换布局的。

    目前只做了这两种布局,后面还得加主题,搞完这套我就丢git上。

    弱鸡程序员年底还在加班
  • 海星吧 2022-7-23
    0 6

    https://acgn.zone/thread-14203.htm

    分享这个项目git的文章

    弱鸡程序员年底还在加班
  • 海星吧 2022-7-23
    0 7
    奈何桥头逗鬼 看来我学编程的道路还很长啊~
    没啥难的,前端用vue的多看文档就行了。
    弱鸡程序员年底还在加班
    • ACG里世界
      8
          
返回
发新帖