Vue 3 + TypeScript 响应式共享状态“失效”的问题根本原因

响应式变量必须是单例,才能在多个地方共享响应式性。


😵‍💫 现象

你在一个 ts 模块中这样写:

// store.ts
import { ref, watch } from 'vue'

export const count = ref(0)

watch(count, (val) => {
  console.log('store 内部监听:', val)
})

然后在另一个地方使用:

// A.vue
import { count } from './store'

watch(count, (val) => {
  console.log('组件 A 的监听:', val)
})

结果你发现:

  • store.ts 中的监听正常触发

  • 在其他地方 watch(count, ...) 却监听不到变化?


✅ 根本原因

你可能犯了 “重新创建响应式变量” 的错误,比如:

  1. 你不是导出 ref 本身,而是导出一个函数,每次都创建新的 ref

  2. 你多次导入或者某些环境中有热更新导致 store.ts 被多次执行

  3. 你用了 defineExpose() 或类似语法暴露变量,但不是响应式的 ref 本身


✅ 正确的做法:确保响应式变量是单例!

❗ 错误示例

// ❌ 每次调用 useCount 都创建新的 ref,失去响应式共享
export function useCount() {
  return ref(0)
}

✅ 正确示例:使用模块作用域变量

// store.ts
import { ref } from 'vue'

const count = ref(0) // 在模块作用域中定义

export function useCount() {
  return {
    count
  }
}

然后其他地方用:

const { count } = useCount()

watch(count, (val) => {
  console.log('组件监听:', val)
})

现在多个地方使用 useCount(),都会共享同一个 ref,响应式就生效了!


✅ 最终建议结构(推荐组合式写法)

// stores/useComponentStore.ts
import { ref, computed } from 'vue'

const components = ref([...])
const activeComponent = computed(() => {
  return components.value.find(item => item.active)
})

export function useComponentStore() {
  return {
    components,
    activeComponent,
    setActiveComponent: (id: string) => {
      components.value.forEach(item => item.active = item.id === id)
    }
  }
}

💡 只要你 export 的变量是在模块作用域创建的,响应式性就能在多个组件中共享。

本作品采用《CC 协议》,转载必须注明作者和本文链接
九九一十八,一步一个脚印
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!