@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,提问作者김도균
相关产品推荐
相关产品推荐

