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

如何让所有可见Vue组件重新获取Apollo查询?含缓存重置场景

实现方案

需求一:触发所有可见Vue组件重新获取Apollo查询

方案1:全局事件总线 + 组件内监听

这个方案适合需要手动触发(比如点击按钮)的场景,能精准控制哪些组件响应:

  1. 设置全局事件总线

    • Vue3 可以用 mitt 库或自定义简单事件发射器:
      // main.js
      import { createApp } from 'vue'
      import App from './App.vue'
      import mitt from 'mitt'
      
      const emitter = mitt()
      const app = createApp(App)
      app.config.globalProperties.$emitter = emitter
      app.mount('#app')
      
    • Vue2 直接用 Vue 实例本身作为总线:
      // main.js
      import Vue from 'vue'
      import App from './App.vue'
      
      Vue.prototype.$bus = new Vue()
      new Vue({ render: h => h(App) }).$mount('#app')
      
  2. 组件内监听事件并触发refetch

    • Vue3 Composition API:
      import { useQuery } from '@vue/apollo-composable'
      import { gql } from 'graphql-tag'
      import { getCurrentInstance, onMounted, onUnmounted } from 'vue'
      
      export default {
        setup() {
          const instance = getCurrentInstance()
          const { refetch } = useQuery(gql`
            query FetchItems {
              items { id name }
            }
          `)
      
          const handleRefetch = () => refetch()
      
          onMounted(() => {
            instance?.proxy?.$emitter.on('refetch-all-apollo-queries', handleRefetch)
          })
          onUnmounted(() => {
            instance?.proxy?.$emitter.off('refetch-all-apollo-queries', handleRefetch)
          })
      
          return { /* 你的数据 */ }
        }
      }
      
    • Vue2 Options API:
      import { gql } from 'graphql-tag'
      
      export default {
        apollo: {
          items: {
            query: gql`query FetchItems { items { id name } }`
          }
        },
        mounted() {
          this.$bus.$on('refetch-all-apollo-queries', () => {
            this.$apollo.queries.items.refetch()
          })
        },
        beforeDestroy() {
          this.$bus.$off('refetch-all-apollo-queries')
        }
      }
      
  3. 触发全局事件
    在需要触发的地方(比如某个按钮点击事件):

    // Vue3
    this.$emitter.emit('refetch-all-apollo-queries')
    // Vue2
    this.$bus.$emit('refetch-all-apollo-queries')
    

方案2:使用Apollo Client的resetStore()

如果你的目标是同时清除缓存并重新获取所有活跃查询,可以直接调用Apollo Client的resetStore()方法:

// Vue3
import { useApolloClient } from '@vue/apollo-composable'

const { client } = useApolloClient()

const refetchAllAndResetCache = async () => {
  await client.resetStore()
}

// Vue2
const refetchAllAndResetCache = async () => {
  await this.$apollo.client.resetStore()
}

这个方法会自动清除InMemoryCache,并重新执行当前所有活跃的查询(可见组件中的查询都会重新获取数据)。


需求二:重置InMemoryCache后让组件自动响应

方案1:用resetStore()替代单独的cache.reset()

如上述方案,resetStore()会在清除缓存后自动重新执行所有活跃查询,组件无需额外代码就能获取最新数据。这是最省心的方式。

方案2:手动重置缓存后触发全局事件

如果你必须单独调用cache.reset()(比如不想重新执行所有查询,只针对部分组件),可以在重置缓存后触发之前设置的全局事件:

// Vue3
import { useApolloClient } from '@vue/apollo-composable'

const { client } = useApolloClient()

const resetCacheAndRefetch = async () => {
  await client.cache.reset()
  // 触发全局事件让组件重新获取
  client.proxy?.$emitter.emit('refetch-all-apollo-queries')
}

// Vue2
const resetCacheAndRefetch = async () => {
  await this.$apollo.client.cache.reset()
  this.$bus.$emit('refetch-all-apollo-queries')
}

方案3:设置查询的fetchPolicy

对于部分组件,你可以设置查询的fetchPolicy为cache-and-network,这样当缓存被重置后,组件会自动从网络获取最新数据(即使缓存为空):

// Vue3
const { result } = useQuery(gql`query FetchItems { items { id name } }`, null, {
  fetchPolicy: 'cache-and-network'
})

// Vue2
apollo: {
  items: {
    query: gql`query FetchItems { items { id name } }`,
    fetchPolicy: 'cache-and-network'
  }
}

这个方式适合不需要全局触发,只希望单个组件在缓存变化时自动响应的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:06:31