vue3的传送门teleport究竟有多神奇?suspense发起异步请求有多简约?

teleport和suspense

一文讲解vue3的Teleport和Suspense

  • 一、👋用teleport实现打开模态框操作
    • 1、teleport是什么
    • 2、实现模态框功能
      • (1)设置锚点
      • (2)定义子组件
      • (3)定义父组件
  • 二、🤚用Suspense
    • 1、Suspense是什么
    • 2、用Suspense发起一个异步请求
    • 3、用Suspense发起多个异步请求
    • 4、如何抓取错误
  • 三、🖐️结束语

大家都知道,在我们平常的前端开发中,实现模态框和发起异步请求是再常见不过的事情了。但是呢,不管是用vue2和原生js的实现方式,从逻辑上来说都还不够独立,因此,vue3推出了新的方法来解决此问题。

下面就带领大家一起来了解vue3新推出的 teleport 究竟有多神奇?以及如何用 suspense 发起多个异步的请求?

一起来学习吧~📚

一、👋用teleport实现打开模态框操作

1、teleport是什么

teleport,字面意思就是远距离传送,我们可以把它理解为传送门的意思。

大家都知道,传送门的意思就是从一个地方传送到了另外一个地方。而 vue3 为什么要用 teleport 来表达呢?

其实,有一个非常常见的需求就是,我们经常要通过点击一个按钮,来实现模态框的效果。而在 vue3 之前,我们基本上控制它都是点击后上下会形成一个父子组件的关系,这样子感觉独立性就没有那么强了。

模态框

因此, vue3 为了解决该问题,就用了 teleport 来解决。 teleport 就仿佛一个传送门,像上图这样,比如我们点击了打开按钮,那么点击完了之后,使用传送门瞬间移动到另外一个地方(模态框 Model )。再点击关闭按钮传送门模态框 Modal 就消失了。

通过这样的解释,相信大家对 teleport 有了一个基础的认识。

2、实现模态框功能

接下来我们就来用这个功能,实现一个模态框,控制组件的显示和隐藏。

(1)设置锚点

我们现在 vue3 项目下的 /public/index.html 设置一个锚点,来放置组件的内容。具体代码如下:

<body><noscript><strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div>//先行定义一个锚点<div id="modal"></div><!-- built files will be auto injected --></body>

(2)定义子组件

接下来我们在 /src/components 下定义一个子组件,命名为 Modal.vue具体代码如下:

<template><teleport to="#modal"><div id="center" v-if="isOpen"><h2><slot>this is a modal</slot></h2><button class="btn2" @click="buttonClick">Close</button></div></teleport>
</template><script>
import { defineComponent } from 'vue'
export default defineComponent({//父组件的数据需要通过props把数据传给子组件,props的取值可以是数组也可以是对象props: {isOpen: Boolean,},//子组件向父组件传递数据//使用emits,更明确的显示组件的自定义事件有哪些emits: {'close-modal': null},//props对应props的内容//context名字可以自定义,只要上下对应即可,用来触发emit的内容setup(props, context){const buttonClick = () => {context.emit('close-modal')}return{buttonClick}}
})
</script><style>
#center{width:200px;height:200px;border:2px solid rgb(105, 165, 56);text-align: center;border-radius: 2px;margin: 50px auto 0;
}
.btn2{background: #1971c9;border:none;padding: 8px;border-radius: 5px;color: #fff;cursor: pointer;
}
</style>

(3)定义父组件

之后我们再来定义一个父组件,命名为 index.vue具体代码如下:

<template><button class="btn1" @click="openModal">打开模态框</button><modal :isOpen="modalIsOpen" @close-modal="onModalClose">My Modal!!!</modal>
</template><script lang="ts">
import { ref, defineComponent} from 'vue'
import Modal from './components/Modal.vue'export default defineComponent({name: 'App',components: {Modal},setup(){//添加响应式对象控制是否显示const modalIsOpen = ref(false)//打开模态框事件const openModal = () => {modalIsOpen.value = true}//关闭模态框事件const onModalClose = () => {modalIsOpen.value = false}return{modalIsOpen,openModal,onModalClose}}
});
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2d4c6b;margin-top: 60px;
}
.btn1{background: #1971c9;border:none;padding: 16px;border-radius: 5px;color: #fff;cursor: pointer;
}
</style>

现在我们来看下浏览器的显示效果:

模态框显示

大家可以看到,通过 teleport 的方式,现在的模态框成功显示在 idappdiv 同一层下,达到了相互独立,而不再是父子层级的结果。

在上面的案例中,我们学习到了通过使用 vue3 新推出的 teleport 特性,将组件渲染到另外一个 DOM 节点的方法,这样使得组件之间的独立性更强。

二、🤚用Suspense

1、Suspense是什么

我们都知道,在 web 世界中,经常遇到很多的异步请求困境。在发起异步请求时,我们往往需要去判断这些异步请求的状态,然后呢,根据这些请求来展示不同的界面。

那现在呢, vue3 推出了一个新的内置组件 SuspenseSuspense 是一个特殊的组件,它会有两个 template slot ,刚开始会渲染 feedback 内容,直到达到某个条件以后,才会渲染正式的内容,也就是default的内容。这样呢,进行异步内容的渲染就会变得特别简单。

同时值得注意的是,如果使用 Suspense ,要返回一个 promise 而不是一个对象。

2、用Suspense发起一个异步请求

接下来我们使用 Suspense发起一个异步请求

首先我们在项目下定义一个子组件,命名为 AsyncShow.vue具体代码如下:

<template><h1>{{result}}</h1>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({setup() {//使用Suspense需要返回一个对象return new Promise((resolve) => {setTimeout(() => {return resolve({result: '10000'})}, 3000)})}
})
</script>

之后在项目下再定义一个父组件,命名为 DogShow.vue具体代码如下:

<template><div id="app"><Suspense><template #default><async-show /></template><template #fallback><h1>Loading !...</h1></template></Suspense></div>
</template><script lang="ts">
import { defineComponent } from 'vue'
import AsyncShow from './components/AsyncShow.vue'export default defineComponent({name: 'App',components: {AsyncShow,},setup() {}
});
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
h1 {font-size: 6rem;
}
</style>

最终浏览器的显示效果如下:

发起一个异步请求

大家可以看到,通过 Suspense ,可以很轻易的发起一个异步请求。刚开始是fallback状态,之后达到 3s 的时间之后,切换到default的状态,显示出对应的异步请求内容。

3、用Suspense发起多个异步请求

我们不满足于现状,且互联网千奇百怪的,我们总不能一直只发送一个异步请求吧!所以,接下来我们就来实现发起多个异步请求的效果。

首先我们用一个免费的在线API ,来发起一个请求。接下来我们在项目的 components 文件下,再定义一个子组件,命名为 DogShow.vue具体代码如下:

<template><img :src="result && result.message">
</template>
<script lang="ts">
import axios from 'axios'
import { defineComponent } from 'vue'
export default defineComponent({async setup() {const rawData = await axios.get('https://dog.ceo/api/breeds/image/random')return {result: rawData.data}}
})
</script>

接下来我们再把以上子组件的内容添加到父组件中,具体代码如下:

<template><div id="app"><Suspense><template #default><async-show /><dog-show /><template #fallback><h1>Loading !...</h1></template></Suspense></div>
</template><script lang="ts">
import AsyncShow from './components/AsyncShow.vue'
import DogShow from './components/DogShow.vue'export default {name: 'App',components: {AsyncShow,DogShow},setup() {}
};
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
h1 {font-size: 6rem;
}
</style>

最终浏览器的显示效果如下:

发起多个请求

大家可以看到,我们同时发起了两个异步请求,并且在Suspense中的default插槽里面同时使用。同样的,浏览器会先显示fallback的内容,之后等到时机到了,就显示我们请求的内容。

依据这样的例子,显示更多的请求也同样有效。这样对比起来,发送多个异步请求是不是就方便了许多。

4、如何抓取错误

学完上面的内容,相信大家对Suspense的用法已经有所了解。那么,网络请求千奇百怪的,总不能每次都能够很顺畅的发起请求对吧。所以呢,我们来需要再来学习一下,当网络请求失败时,如何抓取Supsense包裹下的错误

这个时候我们可以使用一个钩子函数,这个函数叫做 onErrorCaptured ,接下来我们来看下怎么抓取。

我们将父组件 index.vue 进行改造,具体代码如下:

<template><div id="app"><p>{{error}}</p><Suspense><template #default><async-show /><dog-show /><template #fallback><h1>Loading !...</h1></template></Suspense></div>
</template><script lang="ts">
import { onErrorCaptured } from 'vue'
import AsyncShow from './components/AsyncShow.vue'
import DogShow from './components/DogShow.vue'export default {name: 'App',components: {AsyncShow,DogShow},setup() {const error = ref(null)onErrorCaptured((e: any) => {error.value = ereturn true})return{error}}
};
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
h1 {font-size: 6rem;
}
</style>

此时我们再将 DogShow.vue 的接口进行修改,让其变成一个无效的API。代码如下:

const rawData = await axios.get('https://dog.ceo/api/breeds/image')

接下来我们就来看一下浏览器的运行效果:

如何抓取错误

大家可以看到,修改成无效的 API 后,狗狗的图片也不显示了,最后最上方就是通过 onErrorCaptured 这个生命周期捕捉到的错误,清晰明了。

三、🖐️结束语

到这里, teleportSuspense 的内容就讲解结束啦!相信大家对传送门的神奇之处也有了一定的了解,对 Suspense 的独到之处也感受了一番。

vue3持续学习,更新永不停歇……

  • 关注公众号 星期一研究室 ,第一时间关注学习干货,更多有趣的专栏待你解锁~
  • 如果这篇文章对你有用,记得 一键三连 再走哦~
  • 我们下期见!🥂🥂🥂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【BCVP】实现基于 Redis 的消息队列

聆听自己的声音如果自己学不动了&#xff0c;或者感觉没有动力的时候&#xff0c;看看书&#xff0c;听听音乐&#xff0c;跑跑步&#xff0c;休息两天&#xff0c;重新出发&#xff0c;偷懒虽好&#xff0c;可不要贪杯。话说上回书我们说到了&#xff0c;Redis的使用修改《【B…

leetcode18. 四数之和(双指针)

一&#xff1a;题目 二&#xff1a;上码 class Solution { public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int> >ans;vector<int> v;sort(nums.begin(),nums.end());for(int i 0; i < nums…

过去3个多月的1200个小时里,我收获了什么?| 2021年年中总结

&#x1f55b;序言 今年三月初&#xff0c;善后了上学期事情之后&#xff0c;我开始在想&#xff0c;我的未来规划。 身边的好朋友和同学都在筹划着自己的未来&#xff0c;考研的考研&#xff0c;考公的考公。父母和老师们也在劝我说考研&#xff0c;问我考不考研。 依稀记得…

WPF 消息框 TextBox 绑定新数据时让光标和滚动条跳到最下面

WPF 消息框 TextBox 绑定新数据时让光标和滚动条跳到最下面独立观察员 2020 年 9 月 3 日我们在使用 WPF 的 TextBox 作为消息展示框时&#xff0c;如果想在出现滚动条之后&#xff0c;新消息到来时还能够被看到&#xff0c;也就是说让滚动条始终在最下面&#xff0c;或者说光标…

leedcode344. 反转字符串

一:题目 二:上码 class Solution { public:void reverseString(vector<char>& s) {//双指针for(int i 0,j s.size() - 1; i < s.size()/2; i,j--) {swap(s[i],s[j]);}} };

组件库实战 | 用vue3+ts实现全局Header和列表数据渲染ColumnList

用vue3ts实现全局Header和列表数据渲染ColumnList&#x1f5bc;️序言&#x1f4fb;一、ColumnList数据渲染1、设计稿抢先知2、数据构思3、视图数据绑定4、数据传递5、挠头情况☎️二、GlobalHeader全局Header1、设计稿抢先看2、数据构思3、视图数据绑定4、数据传递&#x1f4f…

初识ABP vNext(8):ABP特征管理

点击上方蓝字"小黑在哪里"关注我吧定义特征应用特征用户数量社交登录前言上一篇提到了ABP功能管理&#xff08;特征管理&#xff09;&#xff0c;它来自ABP的FeatureManagement模块&#xff0c;ABP官方文档貌似还没有这个模块的相关说明&#xff0c;但是个人感觉这个…

.NET Core 中导入导出Excel

操作Excel是一个比较常见的业务场景&#xff0c;本篇将使用EPPlus简单演示一个导入导出的示例。EPPlus开源地址&#xff1a;https://github.com/EPPlusSoftware/EPPlus在项目中添加EPPlus组件Install-Package EPPlus导入先准备一个Excel文件&#xff0c;将其内容读取出来&#…

不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识

一文了解webpack入门核心知识&#x1f3a8;序言&#x1f4c5;一、webpack究竟是什么1、写在前面2、什么是模块打包工具&#xff1f;&#x1f4d0;二、如何用Webpack搭建环境1、安装node2、创建项目3、初始化项目4、安装webpack5、安装具体版本的webpack⚙️三、Webpack的配置文…

剑指 Offer 05. 替换空格(两种做法)

一:题目 二:上码 1:方法一 class Solution { public:string replaceSpace(string s) {string str "";for(int i 0; i < s.size(); i) {if(s[i] ){str "%20";}else{str s[i];}}return str;} };2:方法二&#xff08;双指针&#xff09; class So…

.NET Core 中生成验证码

在开发中&#xff0c;有时候生成验证码的场景目前还是存在的&#xff0c;本篇演示不依赖第三方组件&#xff0c;生成随机验证码图片。先添加验证码接口public interface ICaptcha {/// <summary>/// 生成随机验证码/// </summary>/// <param name"codeLeng…

10分钟手把手教你用Android手撸一个简易的个人记账App

用Android手撸一个简易的个人记账系统⛱️序言&#x1f4cb;一、系统结构设计Design1. 需求分析2. 数据库设计3. 界面设计4. 过程设计&#x1f4d8;二、编码阶段Coding1. 项目结构&#x1f5c2;️&#xff08;1&#xff09;文件目录&#xff08;2&#xff09;AndroidManifest.x…

像素级调整,高效转换——轻松提升你的图片处理体验!

探索更高级的图片处理体验&#xff0c;我们为你带来像素级调整与高效转换的完美结合&#xff01;借助我们的专业工具&#xff0c;轻松调整图片像素&#xff0c;让你在细节处展现无限创意&#xff0c;提升作品质感。 第一步&#xff0c;进入首助编辑高手主页面&#xff0c;可以看…

ABP VNext实践之搭建可用于生产的IdentityServer4

一、前言用了半年多的abp vnext&#xff0c;在开发的效果还是非常的好&#xff0c;可以说节省了很多时间&#xff0c;像事件总线、模块化开发、动态API进行远程调用、自动API控制器等等&#xff0c;一整套的规范&#xff0c;让开发人员更方便的集成&#xff0c;提升效率&#x…

151. 翻转字符串里的单词(思路+详解)

一:题目 二:上码 class Solution { public://利用双指针使除去多余的空格,定义快慢指针&#xff0c;最后满指针指向的位置就是除去冗余空格后的字符串//大小void removespacing(string& s){int slowIndex 0,fastIndex 0;//去掉字符串前面的字符while(s.size() > 0 &a…

一文了解树在前端中的应用,掌握数据结构中树的生命线

一文了解树在前端中的应用&#x1f3d5;️序言&#x1f332;一、树是什么&#xff1f;&#x1f334;二、深/广度优先遍历1、深度优先遍历&#xff08;1&#xff09;定义&#xff08;2&#xff09;口诀&#xff08;3&#xff09;代码实现2、广度优先遍历&#xff08;1&#xff0…

【追加功能】OFFICE插件管理工具重整后再上路,更好用易用。

现在使用OFFICE插件的群体越来越多&#xff0c;在8月份修复过的【OFFICE插件管理工具】&#xff0c;尝试将COM加载项的插件管理进行完善。但仍然有一小部分普通加载项的管理未能加到里面。特别是近期用户反馈到的EasyShu插件不能取消加载问题&#xff08;这个是一个bug&#xf…

剑指 Offer 58 - II. 左旋转字符串

一:题目 二:上码 class Solution { public:string reverseLeftWords(string s, int n) {string str1 s.substr(0,n);//(开始位置&#xff0c;个数)string str2 s.substr(n);return str2str1;} };

太平洋大西洋水流问题如何解决?一文了解图在前端中的应用

一文了解图在前端中的应用&#x1f3a7;序言&#x1f3a4;一、图是什么&#xff1f;1、定义2、举例&#x1f3b9;二、图的表示法1、邻接矩阵表示法2、邻接表表示法&#x1f3ba;三、图的常用操作1、图的深度优先遍历&#xff08;1&#xff09;定义&#xff08;2&#xff09;口诀…

统信发布UOS V20 进军个人市场 生态日益完善

日前&#xff0c;统信桌面操作系统V20个人版正式发布&#xff0c;统信UOS是国产操作系统中屈指可数的在民间拥有一批爱好者和发烧友的操作系统&#xff0c;本次统信发布UOS V20个人版&#xff0c;吹响了进军TO C市场的号角。根据官方宣传介绍&#xff0c;统信桌面操作系统V20个…