Vue3 Suspense实现父级加载触发子组件动画直至请求完成
实现父级触发子组件加载状态的方案
核心思路
通过Pinia的loading状态控制父组件的渲染逻辑:数据加载完成前,渲染与真实子组件数量匹配的加载占位;加载完成后,渲染真实子组件并填充数据。
步骤1:修改父组件模板与逻辑
<template lang="pug"> section.discover-row div.discover-row-carousel <!-- 加载中:渲染8个加载占位(数量可根据需求调整) --> div.loading-div( v-for="i in 8" :key="`loading-${i}`" v-show="DiscoverItemStore.loading" ) CHILD LOADING !! <!-- 加载完成:渲染真实子组件 --> DiscoverItem( v-for="(item, index) in DiscoverItemStore.automobiles" :key="item._id" :item="item" :index="index" v-show="!DiscoverItemStore.loading" ) </template> <script setup> import { useDiscoverItemStore } from "@/stores/DiscoverItemStore" const DiscoverItemStore = useDiscoverItemStore() // 触发数据请求 DiscoverItemStore.fetchItems() </script>
步骤2:优化子组件(可选,无需Suspense)
如果想让子组件自主处理状态显示,可移除内部Suspense,改为根据传入的item判断:
<template> div.item-wrapper div.item(v-if="item") SHOW SOME STUFF div.loading-div(v-else) CHILD LOADING !! </template> <script setup> defineProps({ item: { type: Object, default: null }, index: Number }) </script>
对应父组件可简化为预渲染固定数量的子组件,数据加载完成后自动填充内容:
<template lang="pug"> section.discover-row div.discover-row-carousel DiscoverItem( v-for="i in 8" :key="`item-${i}`" :item="DiscoverItemStore.automobiles[i] || null" :index="i" ) </template>
关键说明
- 依赖Pinia中
fetchItems方法的loading状态:确保请求开始时设为true,结束后设为false(你的现有代码已实现该逻辑) - 加载占位的数量可根据接口预期返回的数据量调整,或通过计算属性动态获取分类总和(比如
Cars.length + Suvs.length + Trucks.length + Vans.length) - 使用
v-show切换状态可保留DOM结构提升渲染性能;若使用v-if则会销毁重建DOM
内容的提问来源于stack exchange,提问作者Nick Bewley
相关产品推荐
相关产品推荐

