You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+Vite+TS路由切换时如何实现加载组件的状态控制?

解决Vue3+Vite+TypeScript项目中路由切换时加载界面的状态传递问题

原代码存在的问题

  • router.afterEach里用var isLoading = false声明了局部变量,和全局的isLoading不是同一个,根本无法修改全局状态。
  • 全局的isLoading不是响应式变量,即使能传递到App.vue,视图也不会自动更新。

方案一:通过响应式变量共享状态

在路由文件中创建响应式的加载状态并导出,在App.vue中导入使用:

  1. 修改router/index.ts:
import { createRouter, createWebHistory } from 'vue-router'
import { ref } from 'vue'
// 创建响应式的加载状态并导出
export const isLoading = ref(false)

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    // 你的路由配置
  ]
})

router.beforeEach((to, from, next) => {
  isLoading.value = true
  setTimeout(() => {
    next()
  }, 2000)
})

router.afterEach(() => {
  // 直接修改响应式变量的值,不要重新声明
  isLoading.value = false
})

export default router
  1. 在App.vue中使用:
<script setup lang="ts">
import { isLoading } from './router'
import Preloader from './views/Preloader.vue'
</script>

<template>
  <!-- 根据isLoading的值切换Preloader的类 -->
  <Preloader :class="{ 'active': isLoading }" />
  <router-view />
</template>

<style scoped>
/* 示例样式:根据active类控制加载组件显示/隐藏 */
.active {
  display: block;
}
</style>

方案二:在App.vue内直接管理路由状态

如果加载状态只需要在App.vue中使用,可以直接在App.vue里监听路由钩子,无需跨文件传递状态:

<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import Preloader from './views/Preloader.vue'

const router = useRouter()
const isLoading = ref(false)

// 注册路由前置钩子
router.beforeEach((to, from, next) => {
  isLoading.value = true
  setTimeout(() => {
    next()
  }, 2000)
})

// 注册路由后置钩子
router.afterEach(() => {
  isLoading.value = false
})
</script>

<template>
  <Preloader :class="{ 'active': isLoading }" />
  <router-view />
</template>

注意事项

  • 确保Preloader组件的样式正确,比如默认隐藏,添加active类时显示加载动画。
  • 如果路由切换本身耗时(比如懒加载组件),可以把setTimeout替换为实际的异步加载完成逻辑,而不是固定延迟。

内容的提问来源于stack exchange,提问作者Larry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 17:40:17