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組件使用步驟:

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);
         onErrorCaptured(e=>{
            errMsg.value="出錯了"
            return true   //必須return true上傳上去才能使用
         })
         return{errMsg}
      }
   }
</script>
<style scoped>
</style>

 此時我們把async2.vue中的地址寫錯,我們打開瀏覽器可以看到顯示了錯誤信息,提示我們接口是錯誤的

 

 上面的示例中,我們顯示的后備預顯示的內容,直接解決了異步操作,如果出了什么問題被拒絕,使用onErrorCaptured鈎子捕獲錯誤,將其傳遞給errMsg屬性並在模板中顯示,而不是回退內容

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM