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

