Vue3中ref赋值非响应式数组后多次点击页面不更新的问题
问题描述
以下是我的Vue3代码:
<template> <div> <div class="lockcontent" v-show="lock.length"> Lock : <template v-for="(item2) in lock"> <div class="container"> <span>{{ item2.name }}</span> </div> </template> </div> <button @click="handleLockData"> Add</button> </div> </template> <script setup lang="ts"> const lock = ref<any[]>([]) const newarr =[1,2,3,4] const handleLockData = () => { newarr.push(Math.random()) lock.value = newarr } </script>
点击按钮时先向非响应式数组newarr添加随机值,再将newarr赋值给ref变量lock.value。首次点击按钮时页面能正常更新显示新值,但第二次及之后点击页面不再更新,请问这是什么原因?
我尝试调试并查看源码,发现这种给非响应式变量添加值的方式不会进入nexttick,但不清楚具体原因,猜测是引用类型数据导致的问题。
原因分析与解决方案
核心原因
Vue的响应式系统是通过检测引用变化触发更新的。lock是ref包装的响应式数组,第一次赋值时lock.value指向了newarr的内存地址。后续点击时,你只是给newarr追加元素,再把同一个数组对象赋值给lock.value——此时lock.value的引用地址完全没变,Vue感知不到变化,自然不会触发页面更新。
修复方案
有两种简单可行的修复方式:
- 创建新数组赋值:每次赋值时生成新数组,让
lock.value的引用地址改变,触发响应式更新:
const handleLockData = () => { newarr.push(Math.random()) lock.value = [...newarr] // 通过展开运算符创建新数组 }
- 直接操作响应式数组:跳过非响应式的
newarr,直接修改lock.value这个响应式数组,Vue能检测到数组的变更操作:
const handleLockData = () => { lock.value.push(Math.random()) }
如果需要保留newarr的同步更新,也可以这么写:
const handleLockData = () => { const randomVal = Math.random() newarr.push(randomVal) lock.value.push(randomVal) }
内容的提问来源于stack exchange,提问作者More
相关产品推荐
相关产品推荐

