Suspense组件

何时使用Suspense

在vue2.0时代我们必须使用条件(v-if或v-else)来检查我们的数据是否已加载并显示后备内容。

在vue3.0中内置了Suspense,因此我们不必担心何时加载数据并呈现相应的内容

Suspense是什么

Suspense组件作用是当你在进行一个异步加载时,先提供一些静态组件作为显示内容,然后当异步加载完毕时再显示

Suspense组件会暂停你的组件渲染,重现一个回落组件,直到满足条件为止。

Suspense的使用

Suspense组件是vue3推出的一个内置特殊组件,只是一个内置标签,不需要引入直接使用就可以,必须需要返回一个Promise,而不是json对象

Suspense组件是一个具有插槽的组件,是根据插槽机制来区分组件的,#default插槽内容是你需要渲染的异步组件(需要返回一个promise);#fallback是你指定的加载中的静态组件

defineComponent:defineComponent是用来解决在Typescript环境中,传统的Vue.extend无法对组件给出正确的类型判断,也就是说在Typescript环境中如果参数类型不正确时,用defineComponent()组件来进行包装函数

<template>
    <div>
    </div>
</template>
<script>
import {defineComponent} from "vue"
    export default defineComponent ({

    })
</script>
<style scoped>
</style>

 app.vue

<template>
   <div>
      <Suspense>
         <template #default>   <!--#default插槽内容是你需要渲染的异步组件(需要返回一个promise)-->
            <async></async>
         </template>
         <template #fallback><!--#fallback是你指定的加载中的静态组件-->
            loading...
         </template>

      </Suspense>
   </div>
</template>

<script>
import async from "./components/async.vue"
   export default {
      components:{
         async
      }
   }
</script>
<style scoped>
</style>

 async.vue

<template>
    <div>
    {{result}}
    </div>
</template>
<script>
import {defineComponent} from "vue"
    export default defineComponent ({
       setup(){
            return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve({result:'hello'})
            },2000)
        })
       }
    })
</script>
<style scoped>
</style>

 此时我们打开浏览器发现在前2秒,定时器还没有工作时加载的是指定的加载中的静态组件loading...,2秒钟过会才会加载出hello                                                 

 Suspense组件Suspense组件

 

 

 Suspense组件使用步骤:

1>新建一个异步组件,需要返回一个promise

2>将异步组件包装在<template #default>标签中

3>在异步组件旁边添加一个兄弟组件标签为<template #fallback>

4>将两个组件包装在<Suspense>组件中

 Suspense加载多个组件

我们新建一个async.vue组件

<template>
    <div>
    <ul>
        <li v-for="(item,index) in result" :key="index">{{item.title}}</li>
    </ul>
    </div>
</template>
<script>
import {defineComponent} from "vue"
import axios from "axios"
    export default defineComponent ({
       async setup(){
           let data=await axios.get("http://jsonplaceholder.typicode.com/posts?userId=2")  //一个开源的接口地址
           console.log(data)
           return {result:data.data}
       }
    })
</script>
<style scoped>
</style>

 app.vue

<template>
   <div>
      <Suspense>
         <template #default>   <!--#default插槽内容是你需要渲染的异步组件(需要返回一个promise)-->
            <async></async>
            <async2></async2>
         </template>
         <template #fallback><!--#fallback是你指定的加载中的静态组件-->
            loading...
         </template>

      </Suspense>
   </div>
</template>

<script>
import async from "./components/async.vue"
import async2 from "./components/async2.vue"

   export default {
      components:{
         async,
         async2
      }
   }
</script>
<style scoped>
</style>

 此时页面会弹出一个警告

Suspense组件

 

警告: Suspense是一个实验性的特性,它的API可能会改变slots,除非只有一个根节点

怎么解决:异步组件外增加一个div包裹(增加一个根节点)

<template>
   <div>
      <Suspense>
         <template #default>   <!--#default插槽内容是你需要渲染的异步组件(需要返回一个promise)-->
            <div>
               <async></async>
            <async2></async2>
            </div>
         </template>
         <template #fallback><!--#fallback是你指定的加载中的静态组件-->
            loading...
         </template>

      </Suspense>
   </div>
</template>

此时就不会报错

Suspense组件

 

 如果我们一步请求失败会怎么办呢?

Suspense可以捕获组件错误

使用新的onErrorCaptured生命周期钩子来捕获此类错误并显示正确的错误信息

在vue.中,使用onErrorCaptured钩子函数,无论调用什么,此钩子函数会在捕获的组件的错误时运行,如果出现问题,我们可以将其余的suspense一起使用以渲染错误

app.vue

<template>
   <div>
   <div v-if="errMsg">{{errMsg}}</div>
      <Suspense v-else>
         <template #default>   <!--#default插槽内容是你需要渲染的异步组件(需要返回一个promise)-->
            <div>
               <async></async>
            <async2></async2>
            </div>
         </template>
         <template #fallback><!--#fallback是你指定的加载中的静态组件-->
            loading...
         </template>

      </Suspense>
   </div>
</template>

<script>
import async from "./components/async.vue"
import async2 from "./components/async2.vue"
import {onErrorCaptured,ref} from "vue"
   export default {
      components:{
         async,
         async2
      },
      setup(){
         let errMsg=ref(null);
         one rrorCaptured(e=>{
            errMsg.value="出错了"
            return true   //必须return true上传上去才能使用
         })
         return{errMsg}
      }
   }
</script>
<style scoped>
</style>

 此时我们把async2.vue中的地址写错,我们打开浏览器可以看到显示了错误信息,提示我们接口是错误的

Suspense组件

 

 上面的示例中,我们显示的后备预显示的内容,直接解决了异步操作,如果出了什么问题被拒绝,使用onErrorCaptured钩子捕获错误,将其传递给errMsg属性并在模板中显示,而不是回退内容

 

上一篇:【RTT】SPI Flash 与文件系统(3):DFS 和 EasyFlash


下一篇:Flash Player教育版是什么?和普通版有何区别?