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

@nuxtjs/composition-api中reactive数组的watch与computed不生效问题

问题原因

@nuxtjs/composition-api 底层基于 Vue2 运行,Vue2 的响应式系统存在固有缺陷:直接通过下标修改数组元素、直接修改数组 length 属性都无法触发响应式更新,你当前的下标赋值写法刚好触发了该限制,所以计算属性和监听器都不会执行。

修复方案

你可以选择以下任意一种方式修改赋值逻辑,修改完成后原有的 computed 和 watch 逻辑无需调整即可正常触发。

方案1:使用数组变异方法赋值

Vue2 对 splice 等7个数组原生方法做了响应式劫持,调用这些方法可以正常触发更新,将赋值逻辑替换为 splice 实现即可:

const onUploadProgress = (index: number) => ({ loaded, total }: { loaded: number, total: number }) => {
    console.log('onUploadProgress', progress)
    // 替换原有下标赋值逻辑
    progress.splice(index, 1, Math.round((loaded / total) * 100))
}

方案2:使用set方法显式触发响应式

从 @nuxtjs/composition-api 中导入 set 方法,用来给数组指定下标赋值,会自动标记为响应式更新:

import { set, reactive, computed, watch } from '@nuxtjs/composition-api'

const progress = <any>reactive([])
const onUploadProgress = (index: number) => ({ loaded, total }: { loaded: number, total: number }) => {
    console.log('onUploadProgress', progress)
    // 用set方法赋值
    set(progress, index, Math.round((loaded / total) * 100))
}

方案3:改用ref定义数组

ref 对数组的响应式处理兼容性更好,修改时操作 .value 属性即可,替换整个数组也能触发更新:

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

// 改用ref定义数组
const progress = ref<number[]>([])
const onUploadProgress = (index: number) => ({ loaded, total }: { loaded: number, total: number }) => {
    console.log('onUploadProgress', progress.value)
    // 写法1:用splice修改
    progress.value.splice(index, 1, Math.round((loaded / total) * 100))
    // 写法2:替换整个数组
    // const newArr = [...progress.value]
    // newArr[index] = Math.round((loaded / total) * 100)
    // progress.value = newArr
}

内容的提问来源于stack exchange,提问作者김도균

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:06:00