子組件全數載入前加上loading icon|Waiting for Multiple API Calls to Complete Before Rendering Vue Component

Wendy Chang
Wendy Loops
Published in
5 min readJun 28, 2024

也是provide, inject的應用

假設有一個頁面中包了好幾層的component,紅色框的view會打三個API並props給下面的子組件,深藍色的子組件收到紅色API資料後再打API,並傳遞給淺藍色子組件,淺藍色子組件再將資料emit給橘色子組件:

這時候整個頁面就會頓頓的,等待資料獲取的時間並繪成chart,所以我想要做成等待所有API完成後渲染組件前,先加上loading的遮罩。

實作

父組件定義componentsLoading唯一空物件(new Set()),用來存取loading狀態,並且定義loading中跟loading完成的函式(addLoadingremoveLoading)

<!-- App.vue 或主要父組件 -->
<template>
<div>
<div v-if="isLoading">
<loading-icon></loading-icon>
</div>
<div v-else>
<component-1></component-1>
<component-2></component-2>
<!-- 更多組件... -->
</div>
</div>
</template>

<script setup>
import { ref, provide, computed } from 'vue'
import LoadingIcon from './LoadingIcon.vue'
import Component1 from './Component1.vue'
import Component2 from './Component2.vue'

const componentsLoading = ref(new Set()) // {}

const addLoading = (componentId) => {
componentsLoading.value.add(componentId) //{componentId}
}

const removeLoading = (componentId) => {
componentsLoading.value.delete(componentId)
}
// 如果componentsLoading內還有東西就代表還在load
const isLoading = computed(() => componentsLoading.value.size > 0)

provide('loadingManager', {
addLoading,
removeLoading,
})

</script>

利用porvide/inject將loadingManager方法傳遞給子組件,子組件利用方法更新loading狀態

vue
Copy
<!-- Component1.vue -->
<template>
<div>
<!-- 組件內容 -->
</div>
</template>

<script setup>
import { inject, onMounted } from 'vue'

const { addLoading, removeLoading } = inject('loadingManager')

onMounted(async () => {
const componentId = 'component1'
addLoading(componentId) // 剛載入頁面準備fetchData前先加上loading狀態

try {
// 執行 API 請求
await fetchData()
} catch (error) {
console.error('Error in Component1:', error)
} finally {
removeLoading(componentId) // 完成即移除
}
})

async function fetchData() {
// API
}

</script>

每一個子組件都做一樣的事情

父組件的isLoading會隨時抓取狀態,直到componentsLoading.value變回空物件,isLoading才會變成false,取消loading狀態並把loading icon移除,呈現載入好的頁面。

資料全數載入前都會有這個Loading icon

--

--

Wendy Chang
Wendy Loops

什麼都寫ㄉ前端工程師 / 影片剪輯師 / 自媒體經營者 斗內網址:https://p.ecpay.com.tw/E35E9DE