在 Vue3.2 中,使用 watch
监听父组件传递给子组件的 props.tableData
数组无效。
引用类型监听问题:tableData
是一个数组(引用类型),Vue 的响应式系统默认只监听引用的变化,不监听数组内部元素的变化。
watch 默认行为:默认情况下,watch
是浅监听(shallow watch),对于数组和对象,只有引用变化才会触发回调。
props 不可变性:子组件不能直接修改 props,所以即使数组内容变化,props 的引用可能保持不变。
watch(
() => props.tableData,
(newVal, oldVal) => {
console.log('tableData changed', newVal)
},
{ deep: true } // 添加深度监听
)
watch(
() => props.tableData.length,
(newLen, oldLen) => {
console.log('数组长度变化', newLen)
}
)
const tableDataRef = computed(() => props.tableData)
watch(tableDataRef, (newVal) => {
console.log('tableData changed', newVal)
}, { deep: true })
watchEffect(() => {
console.log('tableData变化:', props.tableData)
})
明确监听目的:如果只需要知道数组是否变化(增删元素),使用 deep: true
;如果关心特定元素变化,可以监听具体属性。
性能考虑:深度监听会有性能开销,特别是大数组,尽量缩小监听范围。
结合 ref 使用:如果需要在子组件操作数据,可以考虑使用 ref
配合 toRefs
:
const { tableData } = toRefs(props)
watch(tableData, (newVal) => {
// 处理变化
}, { deep: true })
props
是响应式的,但不能解构,否则会失去响应性希望这些解决方案能帮助您解决 ref 数组监听问题!