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

Vue3项目如何在用户登录后完成Apollo Client v3全局插件初始化

Vue3 + Apollo Client v3 登录后初始化Apollo Provider实现方案

核心思路

放弃全局提前注册Apollo Provider的常规写法,将Apollo实例初始化逻辑封装为可调用方法,仅在用户登录成功(或检测到本地已存有效登录态)时执行初始化并挂载到Vue实例。

实现步骤

1. 改造main.js暴露Vue实例

移除原有提前初始化Apollo的代码,导出创建好的Vue应用实例,供后续动态挂载provider使用:

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'

const app = createApp(App)
app.use(createPinia())
app.use(router)

// 导出app实例供其他模块调用
export default app

app.mount('#app')

2. 封装Apollo初始化方法

新建utils/apollo.js文件,封装创建Apollo Client和Provider的逻辑,读取登录后存储的token注入请求头:

// utils/apollo.js
import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client/core'
import { DefaultApolloClient } from '@vue/apollo-composable'
import { createApolloProvider } from '@vue/apollo-option'
import app from '../main'

// 初始化方法
export function initApollo() {
  // 从本地存储/状态管理取登录后的token
  const token = localStorage.getItem('auth_token')
  
  const httpLink = createHttpLink({
    uri: '你的GraphQL接口地址',
    headers: {
      Authorization: token ? `Bearer ${token}` : ''
    }
  })

  const apolloClient = new ApolloClient({
    link: httpLink,
    cache: new InMemoryCache(),
    // 按需配置其他参数
  })

  const apolloProvider = createApolloProvider({
    defaultClient: apolloClient,
  })

  // 挂载到Vue实例
  app.use(apolloProvider)
  // 若使用composition API写法,额外注入全局provide
  app.provide(DefaultApolloClient, apolloClient)
  
  // 返回实例方便后续操作
  return apolloClient
}

3. 登录成功后触发初始化

在登录页面的登录成功回调逻辑中,存储token后调用初始化方法:

// 登录页面逻辑
async function handleLogin() {
  // 调用登录接口获取token
  const { token } = await loginApi(loginForm.value)
  // 存储token
  localStorage.setItem('auth_token', token)
  // 初始化Apollo
  initApollo()
  // 跳转到受保护页面
  router.push('/dashboard')
}

4. 适配刷新场景,增加路由守卫判断

用户登录后刷新页面时,本地已存在有效token但Apollo未初始化,需要在路由守卫中补充初始化逻辑:

// router/index.js 路由守卫
import { initApollo } from '../utils/apollo'

router.beforeEach((to, from, next) => {
  const hasToken = localStorage.getItem('auth_token')
  // 访问受保护页面且已登录
  if (to.meta.requiresAuth && hasToken) {
    // 全局挂载标记,避免重复初始化
    if (!window.__apollo_initialized__) {
      initApollo()
      window.__apollo_initialized__ = true
    }
    next()
  } else if (to.meta.requiresAuth && !hasToken) {
    // 未登录跳登录页
    next('/login')
  } else {
    next()
  }
})

可选拓展:退出登录重置Apollo

用户退出登录时,可重置Apollo实例清除缓存,避免用户数据残留:

function handleLogout() {
  localStorage.removeItem('auth_token')
  // 重置初始化标记
  window.__apollo_initialized__ = false
  // 重置Apollo缓存,跳转登录页
  apolloClient.resetStore()
  router.push('/login')
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:36:05