Vue3 Setup监听Prop数组元素数量变化时Watcher为何未触发?
问题分析与解决方案
问题根源
- Ref对象访问错误:用
toRef(props, 'someArray')创建的someArr是Ref实例,必须通过.value才能访问实际数组。你之前写的someArr.length是访问Ref对象本身的length属性(该属性不存在),自然无法触发监听。 - 浅监听限制:Vue的
watch默认是浅监听,仅检测数组的引用变化(比如替换成新数组)。如果父组件通过数组变更方法(如push、splice)或修改内部元素更新数组,数组引用未改变,此时必须开启deep: true才能监听到内部变化。
正确监听写法
方式1:监听Ref数组的变化
<script setup> const props = defineProps({ someArray: { type: Array, default: () => [] } }) const someArr = toRef(props, 'someArray') // 监听数组内部所有变化(元素新增/删除/修改) watch(someArr, () => { console.log('数组内部已更新') }, { deep: true }) // 仅监听数组长度变化 watch(() => someArr.value.length, () => { console.log('数组长度已变化') }) </script>
方式2:直接监听props中的数组
<script setup> const props = defineProps({ someArray: { type: Array, default: () => [] } }) // 监听props数组的内部变化 watch(() => props.someArray, () => { console.log('props数组已更新') }, { deep: true }) // 仅监听props数组的长度变化 watch(() => props.someArray.length, () => { console.log('props数组长度已变化') }) </script>
为什么模板能正常更新
Vue对数组的原生变更方法(push、pop、splice等)做了响应式包装,同时模板渲染时会自动追踪数组的内部依赖,所以即使数组引用未改变,内部元素更新也能触发重新渲染。但watch默认不追踪嵌套对象/数组的内部变化,必须显式开启deep: true才能生效。
内容的提问来源于stack exchange,提问作者AlexMA
相关产品推荐
相关产品推荐

