最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3中的內(nèi)置組件<Suspense>用法

 更新時(shí)間:2025年10月28日 14:43:47   作者:fishmemory7sec  
<Suspense>是 Vue3 中的一個(gè)實(shí)驗(yàn)性功能,用于處理異步組件和依賴(lài),它允許你在等待多個(gè)異步依賴(lài)項(xiàng)解析時(shí)顯示一個(gè)加載狀態(tài),并提供了超時(shí)處理、錯(cuò)誤捕獲和嵌套使用等功能,通過(guò)合理使用<Suspense>,可以提升用戶(hù)體驗(yàn),特別是在處理復(fù)雜異步操作時(shí)

官方文檔:

官方提示:

  • <Suspense> 是一項(xiàng)實(shí)驗(yàn)性功能。它不一定會(huì)最終成為穩(wěn)定功能,并且在穩(wěn)定之前相關(guān) API 也可能會(huì)發(fā)生變化。
  • <Suspense>是一個(gè)內(nèi)置組件,用來(lái)在組件樹(shù)中協(xié)調(diào)對(duì)異步依賴(lài)的處理。它讓我們可以在組件樹(shù)上層等待下層的多個(gè)嵌套異步依賴(lài)項(xiàng)解析完成,并可以在等待時(shí)渲染一個(gè)加載狀態(tài)。

異步依賴(lài)

要了解 <Suspense> 所解決的問(wèn)題和它是如何與異步依賴(lài)進(jìn)行交互的,需要了解什么是異步依賴(lài)。

<Suspense>主要用于包裹異步組件,這些組件可能需要進(jìn)行異步數(shù)據(jù)獲取或其他耗時(shí)的操作:

<Suspense>
└─ <Dashboard>
   ├─ <Profile>
   │  └─ <FriendStatus>(組件有異步的 setup())
   └─ <Content>
      ├─ <ActivityFeed> (異步組件)
      └─ <Stats>(異步組件)

在這個(gè)組件樹(shù)中有多個(gè)嵌套組件,要渲染出它們,首先得解析一些異步資源。

如果沒(méi)有 <Suspense>組件:

  • 以vue2 項(xiàng)目為例:這個(gè)組件樹(shù)中的全部組件,都需要處理各自的加載、報(bào)錯(cuò)和完成狀態(tài)。
  • 在網(wǎng)絡(luò)不好或數(shù)據(jù)量過(guò)大的時(shí)候,可以看到頁(yè)面上有多個(gè)加載狀態(tài),它們?cè)诓煌臅r(shí)間加載完成,頁(yè)面顯示出內(nèi)容。

有了 <Suspense> 組件后:

  • 可以在等待整個(gè)多層級(jí)組件樹(shù)中的各個(gè)異步依賴(lài)獲取結(jié)果時(shí),在頂層展示出加載中或加載失敗的狀態(tài)。

<Suspense> 可以等待的異步依賴(lài)有兩種:

  • 帶有異步 setup() 鉤子的組件。這也包含了使用 <script setup> 時(shí)有頂層 await 表達(dá)式的組件。
  • 異步組件。

async setup()

組合式 API 中組件的 setup() 鉤子可以是異步的:

export default {
  async setup() {
    const res = await fetch(...)
    const posts = await res.json()
    return {
      posts
    }
  }
}

<script setup>語(yǔ)法糖

<script setup>語(yǔ)法糖中,開(kāi)發(fā)者無(wú)法在前面添加async。

如果使用 <script setup>,那么頂層 await 表達(dá)式會(huì)自動(dòng)讓該組件成為一個(gè)異步依賴(lài):

<!-- Child.vue -->
<template>
  <div class="child-box">
    <h1>子組件</h1>
    <h2>網(wǎng)易熱歌榜</h2>
  </div>
</template>
<script setup lang="ts">
// 獲取網(wǎng)易云熱歌榜
let res = await fetch('https://api.uomg.com/api/rand.music?sort=熱歌榜&format=json')
console.log(res.json()) // 一個(gè)Promise
</script>

在父組件中直接引用Child.vue組件:

<template>
  <div class="home-wrap">
    <h1>主頁(yè)----父組件</h1>
    <Child />
  </div>
</template>
<script setup lang="ts">
import Child from './Child.vue';
</script>

頁(yè)面沒(méi)有顯示Child.vue的內(nèi)容,并且在控制臺(tái)提示:

[Vue warn]: Component : setup function returned a promise, but no boundary was found in the parent component tree. A component with async setup() must be nested in a in order to be rendered.

setup函數(shù)返回了一個(gè)promise,但是在父組件樹(shù)中沒(méi)有找到<Suspense> 邊界。帶有async setup()的組件必須嵌套在<Suspense> 中才能呈現(xiàn)。

按照提示修改父組件:

<template>
  <div class="home-wrap">
    <h1>主頁(yè)----父組件</h1>
    <Suspense>
      <!-- 異步任務(wù)ok后 -->
      <template v-slot:default>
        <Child />
      </template>
      <!-- 異步任務(wù)未做完時(shí) -->
      <template v-slot:fallback>
        <div>請(qǐng)求中...</div>
      </template>
    </Suspense>
  </div>
</template>
<script setup lang="ts">
import { Suspense } from 'vue';
import Child from './Child.vue';
</script>

頁(yè)面成功展示Child.vue的內(nèi)容:

異步組件

異步組件默認(rèn)就是suspensible: true的。這意味著如果組件關(guān)系鏈上有一個(gè) <Suspense>,那么這個(gè)異步組件就會(huì)被當(dāng)作這個(gè) <Suspense> 的一個(gè)異步依賴(lài)。在這種情況下,加載狀態(tài)是由 <Suspense> 控制,而該組件自己的加載、報(bào)錯(cuò)、延時(shí)和超時(shí)等選項(xiàng)都將被忽略。

異步組件也可以通過(guò)在選項(xiàng)中指定 suspensible: false 表明不用 Suspense 控制,并讓組件始終自己控制其加載狀態(tài)。

<Suspense>

props

interface SuspenseProps {
  timeout?: string | number
  suspensible?: boolean
}

參數(shù)說(shuō)明:

timeout:可選參數(shù)。

  • 類(lèi)型:string | number
  • 作用:指定一個(gè)超時(shí)時(shí)間。如果異步依賴(lài)在這個(gè)時(shí)間內(nèi)沒(méi)有解析完成,<Suspense>將不再等待并顯示 fallback 內(nèi)容。

suspensible:可選參數(shù)。

  • 類(lèi)型:boolean,默認(rèn)值為 false
  • 作用:當(dāng)設(shè)置為 true 時(shí),組件樹(shù)中所有的異步依賴(lài)將由父級(jí) Suspense 處理。這對(duì)于構(gòu)建復(fù)雜的異步加載場(chǎng)景非常有用,可以將多個(gè)異步依賴(lài)的處理集中在一個(gè)更高層次的 <Suspense> 組件中。

插槽

<Suspense> 組件接受兩個(gè)插槽:#default#fallback。兩個(gè)插槽都只允許一個(gè)直接子節(jié)點(diǎn)。

#default 插槽用于放置異步依賴(lài)的組件或內(nèi)容。

如果在渲染時(shí)遇到異步組件或具有 async setup() 的組件,<Suspense> 會(huì)等待所有異步依賴(lài)項(xiàng)解析完成后再顯示 #default 插槽的內(nèi)容。

#fallback:在異步依賴(lài)解析完成之前,<Suspense> 會(huì)顯示 #fallback 插槽中的內(nèi)容。

<Suspense>
  <!-- 具有深層異步依賴(lài)的組件 -->
  <template #fallback>
    <Dashboard />
  </template>
  

  <!-- 在 #fallback 插槽中顯示 “正在加載中” -->
  <template #fallback>
    Loading...
  </template>
</Suspense>

初始渲染

  • 在初始渲染時(shí),<Suspense>會(huì)開(kāi)始在內(nèi)存中渲染#default插槽的內(nèi)容。
  • 如果<Dashboard />組件(或者它的子組件樹(shù))中包含異步依賴(lài),比如異步組件加載或者async setup()函數(shù),那么在處理這些異步依賴(lài)的過(guò)程中,<Suspense>會(huì)進(jìn)入掛起狀態(tài)。
  • 例如,假設(shè)<Dashboard />組件內(nèi)部,有一個(gè)異步請(qǐng)求數(shù)據(jù)的方法,在數(shù)據(jù)請(qǐng)求期間,<Suspense>就會(huì)進(jìn)入掛起狀態(tài)。

掛起狀態(tài)

  • 在掛起狀態(tài)期間,<Suspense>會(huì)展示#fallback插槽中的內(nèi)容,以向用戶(hù)提供反饋,表明正在進(jìn)行一些異步操作。
  • 例如,當(dāng)<Dashboard />中的異步依賴(lài)正在處理時(shí),用戶(hù)會(huì)看到Loading...

完成狀態(tài)

  • 當(dāng)所有的異步依賴(lài)都完成后,<Suspense>會(huì)進(jìn)入完成狀態(tài),并顯示#default插槽的內(nèi)容。
  • 如果在初次渲染時(shí)沒(méi)有遇到異步依賴(lài),<Suspense>會(huì)直接進(jìn)入完成狀態(tài),直接展示#default插槽的內(nèi)容。

狀態(tài)切換條件

官方說(shuō)明:進(jìn)入完成狀態(tài)后,只有當(dāng)默認(rèn)插槽的根節(jié)點(diǎn)被替換時(shí),<Suspense> 才會(huì)回到掛起狀態(tài)。組件樹(shù)中新的更深層次的異步依賴(lài)不會(huì)造成 <Suspense> 回退到掛起狀態(tài)。

一旦進(jìn)入完成狀態(tài),只有當(dāng) #default 插槽的根節(jié)點(diǎn)被替換時(shí),<Suspense>才會(huì)回到掛起狀態(tài)。

  • 例如,如果<Dashboard />組件被完全替換為另一個(gè)具有異步依賴(lài)的組件,那么<Suspense>會(huì)重新進(jìn)入掛起狀態(tài)。
  • 當(dāng)<Suspense>從完成狀態(tài)因?yàn)?#default 插槽根節(jié)點(diǎn)被替換而回退到掛起狀態(tài)時(shí),后備內(nèi)容不會(huì)立即展示。而是在等待新內(nèi)容和異步依賴(lài)完成的過(guò)程中,仍然展示之前 #default 插槽的內(nèi)容。

通過(guò)設(shè)置 timeout 屬性,配置過(guò)度行為:

  • 在等待渲染新內(nèi)容耗時(shí)超過(guò) timeout 之后,<Suspense> 將會(huì)切換為展示后備內(nèi)容。
  • 設(shè)置 timeout: 0 ,一旦#default插槽的根節(jié)點(diǎn)被替換,就會(huì)立即顯示后備內(nèi)容。

如果只是在<Dashboard />組件的子組件樹(shù)中添加了新的異步依賴(lài),<Suspense>不會(huì)回退到掛起狀態(tài)。

事件

<Suspense> 組件會(huì)觸發(fā)三個(gè)事件:pendingresolvefallback。

@pending 是在進(jìn)入掛起狀態(tài)時(shí)觸發(fā)。

  • 當(dāng)異步依賴(lài)開(kāi)始加載時(shí)觸發(fā)。
  • 可以在這個(gè)事件處理函數(shù)中顯示加載指示器等。

@resolve 是在 default 插槽完成獲取新內(nèi)容時(shí)觸發(fā)。

  • 當(dāng)所有異步依賴(lài)項(xiàng)解析完成時(shí)觸發(fā)。
  • 可以在這個(gè)事件處理函數(shù)中執(zhí)行一些與異步依賴(lài)成功加載相關(guān)的邏輯。

@fallback 是在 fallback 插槽的內(nèi)容顯示時(shí)觸發(fā)。

  • 當(dāng)異步依賴(lài)沒(méi)有在規(guī)定時(shí)間內(nèi)(如果設(shè)置了 timeout)解析完成或者出現(xiàn)錯(cuò)誤時(shí)觸發(fā)。
  • 可以在這個(gè)事件處理函數(shù)中處理錯(cuò)誤情況或顯示特定的 fallback 內(nèi)容。

錯(cuò)誤處理

<Suspense> 組件自身目前還不提供錯(cuò)誤處理,可以使用 errorCaptured 選項(xiàng)或者 onErrorCaptured() 鉤子,在使用到 <Suspense> 的父組件中捕獲和處理異步錯(cuò)誤。

errorCaptured選項(xiàng)

在 Vue 組件的選項(xiàng)中,可以定義errorCaptured方法。這個(gè)方法會(huì)在捕獲到來(lái)自子孫組件(包括異步組件)的錯(cuò)誤時(shí)被調(diào)用。

export default {
  errorCaptured(error, component, info) {
    // 處理錯(cuò)誤的邏輯
    console.log('Error captured:', error);
    // 可以根據(jù)需要返回 false 來(lái)阻止錯(cuò)誤繼續(xù)向上傳播
    return false;
  }
}

參數(shù)說(shuō)明:

error參數(shù)是捕獲到的錯(cuò)誤對(duì)象,component是拋出錯(cuò)誤的組件實(shí)例,info是一個(gè)包含錯(cuò)誤來(lái)源信息的字符串。

當(dāng)在包含<Suspense>的父組件中定義了errorCaptured選項(xiàng)時(shí),如果<Suspense>內(nèi)部的異步組件或異步操作拋出錯(cuò)誤,errorCaptured方法將被調(diào)用。

<template>
  <div>
    <Suspense>
      <template v-slot:default>
        <Child />
      </template>

      <template v-slot:fallback>
        <div>Loading...</div>
      </template>
    </Suspense>
  </div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
  errorCaptured(error, component, info) {
    console.log('Error in Suspense:', error);
  }
});
</script>
<script setup lang="ts">
import { Suspense } from 'vue';
import Child from './Child.vue';
</script>

onErrorCaptured ()鉤子(組合式 API)

在 Vue 3 的組合式 API 中,可以使用onErrorCaptured函數(shù)來(lái)注冊(cè)一個(gè)錯(cuò)誤捕獲鉤子。

<script setup>
import { onErrorCaptured } from 'vue';
onErrorCaptured((error, component, info) => {
  console.log('Error captured with onErrorCaptured:', error);
});
</script>

當(dāng)在包含<Suspense>的父組件中使用onErrorCaptured鉤子時(shí),如果<Suspense>內(nèi)部的異步組件或異步操作拋出錯(cuò)誤,這個(gè)鉤子將被調(diào)用。

注意

errorCaptured方法或onErrorCaptured鉤子中,可以根據(jù)需要返回false來(lái)阻止錯(cuò)誤繼續(xù)向上傳播。

如果不返回false或者返回true,錯(cuò)誤將繼續(xù)向上傳遞給父組件的錯(cuò)誤處理機(jī)制。

嵌套使用

當(dāng)有多個(gè)類(lèi)似于下方的異步組件 (常見(jiàn)于嵌套或基于布局的路由) 時(shí):

<Suspense>
  <component :is="DynamicAsyncOuter">
    <component :is="DynamicAsyncInner" />
  </component>
</Suspense>

<Suspense> 創(chuàng)建了一個(gè)邊界,它將如預(yù)期的那樣解析樹(shù)下的所有異步組件。

  • 當(dāng)更改 DynamicAsyncOuter 時(shí),<Suspense> 會(huì)正確地等待它
  • 當(dāng)更改 DynamicAsyncInner 時(shí),嵌套的 DynamicAsyncInner 會(huì)呈現(xiàn)為一個(gè)空節(jié)點(diǎn),直到它被解析為止 (而不是之前的節(jié)點(diǎn)或回退插槽)。

可以使用嵌套的方法來(lái)解決這個(gè)問(wèn)題:

<Suspense>
  <component :is="DynamicAsyncOuter">
    <Suspense suspensible> <!-- 像這樣 -->
      <component :is="DynamicAsyncInner" />
    </Suspense>
  </component>
</Suspense>

設(shè)置 suspensible 屬性后,所有異步依賴(lài)項(xiàng)處理都會(huì)交給父級(jí) <Suspense> (包括發(fā)出的事件),而內(nèi)部 <Suspense> 僅充當(dāng)依賴(lài)項(xiàng)解析和修補(bǔ)的另一個(gè)邊界。

如果不設(shè)置 suspensible 屬性,內(nèi)部的 <Suspense> 將被父級(jí) <Suspense> 視為同步組件。

這意味著它將會(huì)有自己的回退插槽,如果兩個(gè) Dynamic 組件同時(shí)被修改,則當(dāng)子 <Suspense> 加載其自己的依賴(lài)關(guān)系樹(shù)時(shí),可能會(huì)出現(xiàn)空節(jié)點(diǎn)和多個(gè)修補(bǔ)周期。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue中使用jsencrypt進(jìn)行RSA非對(duì)稱(chēng)加密的操作方法

    Vue中使用jsencrypt進(jìn)行RSA非對(duì)稱(chēng)加密的操作方法

    這篇文章主要介紹了Vue中使用jsencrypt進(jìn)行RSA非對(duì)稱(chēng)加密,在這里需要注意要加密的數(shù)據(jù)必須是字符串,對(duì)Vue?RSA非對(duì)稱(chēng)加密相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-04-04
  • element-ui Upload上傳組件動(dòng)態(tài)配置action方式

    element-ui Upload上傳組件動(dòng)態(tài)配置action方式

    這篇文章主要介紹了element-ui Upload上傳組件動(dòng)態(tài)配置action方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 基于vue2的table分頁(yè)組件實(shí)現(xiàn)方法

    基于vue2的table分頁(yè)組件實(shí)現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了基于vue2的table分頁(yè)組件實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 五分鐘教你使用vue-cli3創(chuàng)建項(xiàng)目(新手入門(mén))

    五分鐘教你使用vue-cli3創(chuàng)建項(xiàng)目(新手入門(mén))

    本文主要介紹了五分鐘教你使用vue-cli3創(chuàng)建項(xiàng)目,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Vue v-model實(shí)現(xiàn)案例介紹

    Vue v-model實(shí)現(xiàn)案例介紹

    v-model就是vue的雙向綁定的指令,能將頁(yè)面上控件輸入的值同步更新到相關(guān)綁定的data屬性,也會(huì)在更新data綁定屬性時(shí)候,更新頁(yè)面上輸入控件的值
    2022-09-09
  • vue源碼之批量異步更新策略的深入解析

    vue源碼之批量異步更新策略的深入解析

    這篇文章主要給大家介紹了關(guān)于vue源碼之批量異步更新策略的相關(guān)資料,關(guān)于vue異步更新是我們?nèi)粘i_(kāi)發(fā)中經(jīng)常遇到的一個(gè)功能,需要的朋友可以參考下
    2021-05-05
  • VUE頁(yè)面中加載外部HTML的示例代碼

    VUE頁(yè)面中加載外部HTML的示例代碼

    本篇文章主要介紹了VUE頁(yè)面中加載外部HTML的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • vue中添加與刪除關(guān)鍵字搜索功能

    vue中添加與刪除關(guān)鍵字搜索功能

    這篇文章主要介紹了vue中添加與刪除,關(guān)鍵字搜索功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-10-10
  • elementUI給el-tabs/el-tab-pane添加圖標(biāo)效果實(shí)例

    elementUI給el-tabs/el-tab-pane添加圖標(biāo)效果實(shí)例

    這篇文章主要給大家介紹了關(guān)于elementUI給el-tabs/el-tab-pane添加圖標(biāo)效果實(shí)例的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用elementUI具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Vue之生命周期函數(shù)詳解

    Vue之生命周期函數(shù)詳解

    這篇文章主要為大家介紹了Vue之生命周期函數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-11-11

最新評(píng)論

神池县| 井冈山市| 奉新县| 和政县| 白河县| 长沙市| 新巴尔虎右旗| 华安县| 饶平县| 沙田区| 项城市| 黎城县| 资兴市| 焉耆| 滦南县| 虞城县| 盐边县| 元江| 淮安市| 荆门市| 安福县| 汾西县| 宣威市| 普定县| 中方县| 福建省| 五河县| 黄浦区| 万州区| 合川市| 宣武区| 洛浦县| 麻江县| 乡宁县| 湘乡市| 岚皋县| 枣庄市| 崇礼县| 宁海县| 建始县| 黄浦区|