You need to enable JavaScript to run this app. Vue2 Composition API composable跨组件共享响应式状态实现咨询
优惠活动
大模型
产品
解决方案
定价
更多

Vue2 Composition API composable跨组件共享响应式状态实现咨询

Vue2 @vue/composition-api 跨组件共享状态正确实现

问题根因

  • 顶层直接声明ref报错:ES 模块导入时会立即执行顶层代码,此时Vue.use(CompositionApi)还未执行,composition-api 运行环境未初始化,调用ref会抛出异常。
  • 函数内每次声明ref状态隔离:每次调用 composable 函数都会生成新的响应式实例,多组件调用时状态不互通,无法联动。

核心解决思路

采用惰性初始化方案,仅在第一次调用 composable 函数时初始化共享响应式状态,此时Vue.use已经执行完毕,不会触发初始化错误。

正确代码实现

modalTrigger.js 代码

import { computed, ref } from '@vue/composition-api'

// 顶层仅声明变量占位,不执行初始化
let modalOpen = null

export default function useModalTrigger() {
  // 第一次调用时才创建响应式实例,后续调用直接复用
  if (!modalOpen) {
    modalOpen = ref(false)
  }

  const getModalOpenState = computed(() => modalOpen.value)
  const setModalOpenState = (state) => {
    console.log('changing state from: ', modalOpen.value, ' to: ', state)
    modalOpen.value = state
  }

  return {
    getModalOpenState,
    setModalOpenState
  }
}

组件使用方式

和原有使用逻辑完全兼容,不需要修改组件代码,所有调用useModalTrigger的组件都会共用同一份响应式状态,修改后自动联动更新。

多模态框扩展方案

如果需要同时管理多个独立模态框的状态,可以给 composable 增加唯一标识参数,用 Map 存储多份状态:

import { computed, ref } from '@vue/composition-api'

const modalStateMap = new Map()

export default function useModalTrigger(modalKey = 'default') {
  if (!modalStateMap.has(modalKey)) {
    modalStateMap.set(modalKey, ref(false))
  }
  const modalOpen = modalStateMap.get(modalKey)

  const getModalOpenState = computed(() => modalOpen.value)
  const setModalOpenState = (state) => {
    modalOpen.value = state
  }

  return {
    getModalOpenState,
    setModalOpenState
  }
}

使用时传入不同标识即可隔离状态:

// 搜索模态框
const { getModalOpenState, setModalOpenState } = useModalTrigger('search')
// 编辑模态框
const { getModalOpenState: getEditModalOpen, setModalOpenState: setEditModalOpen } = useModalTrigger('edit')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 02:12:01