Vue中如何无需修改子组件,在其加载完成前隐藏父组件页脚
实现方案
方案1:使用Vue内置<Suspense>组件(Vue3适用,无需修改子组件)
如果你的项目使用Vue3,直接用Suspense包裹子组件挂载位,结合插槽就能直接控制页脚显隐,全程不需要改任何子组件代码:
父布局代码示例:
<template> <navbar /> <Suspense ref="suspense"> <!-- 子组件加载中显示的占位符(可以和你现有子组件的加载图标保持一致) --> <template #fallback> <div id="main-content"> <div class="loading-icon"></div> </div> </template> <!-- 实际的子组件/路由视图 --> <template #default> <child id="main-content" /> </template> </Suspense> <!-- 页脚和Suspense的加载状态绑定 --> <footer v-if="!$refs.suspense?.isFallback"> Stuff in my footer that should not be shown until the child component is completely loaded </footer> </template>
如果是路由项目直接把child替换成<router-view />即可,所有路由页都会自动生效。
方案2:使用MutationObserver监听DOM变动(Vue2/Vue3通用,无侵入)
如果是Vue2不支持Suspense,可以直接在父组件挂载后监听子组件容器#main-content的DOM变化,当子组件完成数据渲染后DOM结构稳定超过设定阈值就显示页脚,同样不需要修改任何子组件:
父布局代码示例:
<template> <navbar /> <child id="main-content" /> <footer v-if="showFooter"> Stuff in my footer that should not be shown until the child component is completely loaded </footer> </template> <script> export default { data() { return { showFooter: false, domChangeTimer: null } }, mounted() { // 路由切换时重置显示状态 this.$router.beforeEach(() => { this.showFooter = false }) // 监听子组件容器的DOM变动 const observer = new MutationObserver(() => { // 防抖:DOM停止变动300ms后判定为渲染完成,时长可自行调整 clearTimeout(this.domChangeTimer) this.domChangeTimer = setTimeout(() => { this.showFooter = true }, 300) }) observer.observe(document.getElementById('main-content'), { childList: true, subtree: true, attributes: true }) // 组件销毁时清除监听和定时器 this.$once('hook:beforeDestroy', () => { observer.disconnect() clearTimeout(this.domChangeTimer) }) } } </script>
方案3:全局请求统计(适合子组件请求统一封装的场景)
如果你的所有子组件的服务端请求都用了统一的请求工具封装(比如axios),也可以全局维护请求计数器:
- 全局请求拦截器里请求发起时计数器+1,请求结束/报错时计数器-1
- 父组件监听计数器数值,当路由切换后计数器归0时显示页脚
这个方案可以和请求状态完全对齐,不会因为DOM动画、延迟渲染等场景误判加载完成。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

