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

为何此CodeSandbox示例中仅number变量响应式失效?

问题原因分析

你碰到的这个响应式差异问题,核心在于两个composable里ref的更新逻辑和Vue响应式追踪的交互方式不一样:

为什么randomNumber能保持响应式?

在useRandomNumber里,setInterval是调用这个composable时(也就是setup执行阶段)就启动的。此时randomNumber这个ref已经被返回给setup,模板也已开始渲染,Vue的响应式系统已经追踪到randomNumber和模板的绑定关系。所以每次setInterval修改randomNumber.value时,Vue能立刻检测到变化,触发模板更新。

为什么number的响应式会失效?

在useNumber里,addNumber函数修改的是composable内部ref的value,但你通过spread展开返回useNumber()的结果时,模板里绑定的number是Vue自动解包后的普通数值,而非响应式访问器。

简单说:addNumber改的是原始ref的value,但模板显示的是初始解包后的普通值,这个普通值不会自动跟着ref的变化更新——Vue的自动解包只在初始渲染时建立一次关联,后续ref的value变化没法同步到这个普通值上。

修复方法

有两种简单的修复方式:

  • 不使用spread展开,直接返回composable的对象:

    setup() {
      const numberStore = useNumber()
      const randomStore = useRandomNumber()
      return { numberStore, randomStore }
    }
    

    模板里对应改成{{ numberStore.number }}和@click="numberStore.addNumber"。

  • 直接返回ref和函数,不用spread包裹:

    setup() {
      const { number, addNumber } = useNumber()
      const { randomNumber } = useRandomNumber()
      return { number, addNumber, randomNumber }
    }
    

    这种写法和spread看似类似,但Vue对直接返回的ref处理更可靠,能正确维持解包后的响应式关联。

内容的提问来源于stack exchange,提问作者Tom De Smet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 20:47:01