5、Vue3中Teleport和Suspense组件使用

1,369 阅读3分钟

一、Teleport

Teleport在国内大部分都翻译成了瞬间移动组件,它可以把你写的组件挂载到任何你想挂载的DOM上。

为了更好的理解,简单做一个组件的演示,如下:

新建components\Boxtest.vue组件:

<!-- Box -->
<template>
    <div class="Box">
        <h1>Box</h1>
    </div>
</template>

<script lang='ts'>
import {defineComponent} from 'vue'
export default defineComponent({
    name: '',
    setup() {
        return {}
    }
  });
</script>

<style lang='scss' scoped>
    .Box{
        width: 100px;
        height: 100px;
        background: red;
    }
</style>

然后再views\Home.vue中使用Boxtest.vue组件:

<!-- home -->
<template>
    <div>
        <Box/>
    </div>
</template>

<script lang='ts'>
import {defineComponent} from 'vue';
import Box from '../components/Boxtest.vue';
export default defineComponent({
    name: '',
    components:{ Box },
    setup() {
        return {}
    }
  });
</script>

<style lang='scss' scoped></style>

image.png

这时,审查元素你会发现,所有的Dom都是在app节点下的,可能会导致组件样式收到app节点样式影响。如果你想改变节点,在Vue2非常困难。但是在Vue3.x,只需要使用Teleport组件就可以解决。

Teleport方法,可以把Dialog组件渲染到你任意想渲染的外部Dom上,不必嵌套再#app里了,这样就不会互相干扰了。可以把Teleport看成一个传送门,把组件传送到需要的地方。 teleport组件和其它组件没有任何其它的差异,用起来都是一样的。使用也很简单,如下: components\Boxtest.vue修改:

<template>
    <teleport to='#Box'>
        <div class="Box">
            <h1>Box</h1>
        </div>
    </teleport>
</template>

/public/index.html,增加一个Box节点。

  <div id="app"></div>
  <div id="Box"></div>

image.png

这时,组件就不会挂载在app节点,而是挂载在Box节点上。

二、Suspense异步请求组件

开发中,异步请求组件必不可少。比如读取远程图片,比如调用后台接口,这些都需要异步请求。在Vue2.x时代,判断异步请求的状态是一件必须的事情,但是这些状态都要自己处理,根据请求是否完毕展示不同的界面。尤大神深知民间饥苦,在Vue3.x中给我们提供了Suspense组件。

Suspense提供两个template的位置,一个是没有请求回来时显示的内容,一个是全部请求完毕的内容。

注:如果要使用Suspense的话,要返回一个promise对象,而不是原来的那种JSON对象。

如何使用异步请求组件

简单模拟一个异步请求组件,如下:

components\Asynctest.vue

<!-- Async -->
<template>
    <div></div>
</template>

<script lang='ts'>
import {defineComponent} from 'vue'
export default defineComponent({
    name: '',
    setup() {
       return new Promise((resolve, reject) => {
        setTimeout(() => {
                return resolve({ result: "请求成功:200" });
            }, 2000);
        });
    }
  });
</script>

<style lang='scss' scoped></style>

然后再views\Home.vue中使用Asynctest.vue组件:

<!-- home -->
<template>
    <div>
        <Suspense>
            <template #default> <!--default代表异步请求完成后,显示的模板内容。-->
                <Asynctest/>
            </template>
            <template #fallback>
                 <h1>请求中,请耐心等待...</h1> <!--fallback代表在加载中时,显示的模板内容。 -->
            </template>
        </Suspense>
    </div>
</template>

<script lang='ts'>
import {defineComponent} from 'vue';
import Asynctest from '../components/Asynctest.vue';
export default defineComponent({
    name: '',
    components:{ Asynctest },
    setup() {
        return {}
    }
  });
</script>

<style lang='scss' scoped></style>

运行后可以看到,当打开页面时,首先显示的是请求中,请耐心等待...,然后才会显示请求成功:200。也就是promise返回的结果。

image.png

image.png

当使用正式的接口请求是,可以使用promise的语法糖,async...await的写法,如下:

export default defineComponent({
    async setup() {  //promise 语法糖  返回之后也是promise对象
        const res = await axios.get('https://****.***.com/***/***')
        return {result:res.data}
    }
})

处理异步请求错误

在异步请求中必须要作的一件事情,就是要捕获错误,因为我们没办法后端给我们返回的结果,也有可能服务不通,所以一定要进行捕获异常和进行处理。

vue3.x的版本中,可以使用onErrorCaptured这个钩子函数来捕获异常。在使用这个钩子函数前,需要先进行引入。

import { ... , onErrorCaptured} from "vue";

直接在setup()中使用:

setup() {
    onErrorCaptured((error) => {
      console.log(`error====>`,error)
      return true  
    })
    return {};
  }

学习日期:2022/1/14

视频参考www.bilibili.com/video/BV1L5…

文档参考jspang.com/detailed?id…

仅供个人学习和记录