Vue3中Composable响应式数据跨组件不更新问题求助
问题:Vue3组合式函数跨组件响应式同步失败
我在Vue3中编写了useNumbers.js组合式函数,希望numbers数组在组件间保持响应式,但组件A点击按钮添加新数值后,组件B无法同步显示更新后的数据。我知道const { numbers, addNumber } = useNumbers()这类解构操作可能破坏响应式,也尝试过toRef和toRefs,但尚未找到解决方案。相关代码如下:
useNumbers.js
import { ref } from 'vue'; export default function() { const numbers = ref([1, 2, 3, 4, 5]); const addNumber = num => { numbers.value.push(num); } const filterNumber = minNum => { return numbers.value.filter(curNum => curNum >= minNum); } return { numbers, addNumber, filterNumber } }
组件A
<template> <div> <h1>Child component</h1> <p>{{ numbers }}</p> <button @click="addNumber(45)">Add 45</button> <div class="line"></div> <GrandChild /> </div> </template> <script setup> import useNumbers from '../composables/useNumbers'; import GrandChild from './GrandChild.vue'; const { numbers, addNumber } = useNumbers() </script>
组件B
<template> <div> <h1>GreatGrandChild component</h1> <p>{{ numbers }}</p> <div class="line"></div> </div> </template> <script setup> import useNumbers from '../composables/useNumbers'; const { numbers } = useNumbers(); </script>
解决方案
核心问题是每次调用useNumbers()都会创建全新的ref实例,组件A和组件B拿到的是完全独立的两个数组引用,自然无法同步。要实现跨组件共享响应式状态,需要让组合式函数返回同一个ref实例,改成单例模式即可:
修改后的useNumbers.js:
import { ref } from 'vue'; // 将状态定义在函数外部,确保只初始化一次 const numbers = ref([1, 2, 3, 4, 5]); export default function() { const addNumber = num => { numbers.value.push(num); } const filterNumber = minNum => { return numbers.value.filter(curNum => curNum >= minNum); } return { numbers, addNumber, filterNumber } }
这样不管哪个组件调用useNumbers(),拿到的都是同一个numbers ref实例,组件A修改数据后,组件B就能同步响应更新。
另外你之前担心的解构问题,这里其实不影响——因为numbers本身就是ref对象,解构只是把它从返回对象中取出,只要它指向的是同一个实例,响应式就不会丢失。之前的错误本质是实例不共享,而非解构导致的问题。
内容的提问来源于stack exchange,提问作者expatcz
相关产品推荐
相关产品推荐

