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

Vue 3 Composition API(script setup)如何在页面渲染前获取接口数据

Vue3 <script setup> 中实现组件加载前请求数据填充Store的方案

你之前在组件内调用router.beforeEach、router.beforeResolve的写法存在问题:这两个都是全局路由守卫,写在组件内部会导致每次组件挂载都重复注册全局守卫,出现逻辑混乱、多次触发请求的问题,全局守卫应统一在路由初始化文件中定义,不要放在业务组件内。

以下是对应需求的两种标准实现方案:

场景1:仅当前页面/组件需要先加载数据再渲染

直接使用Vue Router 4.1+提供的组合式API组件内守卫onBeforeRouteEnter,和Options API的beforeRouteEnter效果完全一致,会在组件实例创建、页面渲染前触发,阻塞渲染直到守卫逻辑执行完成:

<script setup>
import { onBeforeRouteEnter } from 'vue-router'
import { useUserStore } from '@/stores/user' // 你的Pinia/Vuex store
import { fetchUserInfo } from '@/api/user' // 你的请求API

const userStore = useUserStore()

onBeforeRouteEnter(async (to, from, next) => {
  // 数据不存在时才发起请求,避免重复请求
  if (!userStore.userInfo) {
    const userData = await fetchUserInfo()
    userStore.setUserInfo(userData)
  }
  // 数据加载完成后再放行,进入组件渲染流程
  next()
})
</script>

如果需要在守卫中访问当前组件实例,可通过next的回调参数获取:

onBeforeRouteEnter((to, from, next) => {
  next(vm => {
    // vm即为当前组件实例
    console.log(vm)
  })
})

场景2:全站所有页面都需要先加载公共数据(如用户信息)再渲染

直接在路由初始化文件(通常是/src/router/index.js)中定义全局前置守卫即可:

// /src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { fetchUserInfo } from '@/api/user'

const router = createRouter({
  history: createWebHistory(),
  routes: [/* 你的路由配置 */]
})

router.beforeEach(async (to, from, next) => {
  const userStore = useUserStore()
  // 可通过路由元信息跳过不需要加载用户信息的页面,比如登录页、公共页
  if (to.meta.requiresAuth &&!userStore.userInfo) {
    const userData = await fetchUserInfo()
    userStore.setUserInfo(userData)
  }
  next()
})

export default router

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 04:06:03