ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Suspense组件

2021-11-09 10:34:45  阅读:229  来源: 互联网

标签:vue Suspense import 组件 async defineComponent


何时使用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组件使用步骤:

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是一个实验性的特性,它的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可以捕获组件错误

使用新的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中的地址写错,我们打开浏览器可以看到显示了错误信息,提示我们接口是错误的

 

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

 

标签:vue,Suspense,import,组件,async,defineComponent
来源: https://www.cnblogs.com/keyeking/p/15527623.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有