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
相关产品推荐
相关产品推荐

